// 通知系统
function showNotification(message, type = 'info', duration = 3000) {
    const notificationSystem = document.getElementById('notificationSystem');
    const notification = document.createElement('div');
    notification.className = `notification ${type}`;
    notification.textContent = message;

    notificationSystem.appendChild(notification);

    // 显示动画
    setTimeout(() => {
        notification.classList.add('show');
    }, 100);

    // 自动隐藏
    setTimeout(() => {
        notification.classList.remove('show');
        setTimeout(() => {
            if (notification.parentNode) {
                notification.parentNode.removeChild(notification);
            }
        }, 300);
    }, duration);
}

// 半透明水印：在主体内容中铺设轻度重复标题
function addWatermarkLayer() {
    const existing = document.getElementById('watermarkLayer');
    if (existing) return;
    const wm = document.createElement('div');
    wm.id = 'watermarkLayer';
    wm.style.cssText = [
        'position: absolute',
        'inset: 40px 8px 8px 8px',
        'pointer-events: none',
        'opacity: 0.1',
        'z-index: 9999',
        'background-image: repeating-linear-gradient(45deg, rgba(255,255,255,0.25) 0, rgba(255,255,255,0.25) 1px, transparent 1px, transparent 140px)',
    ].join(';');
    // 叠加标题文本（更隐蔽）
    const text = document.createElement('div');
    text.textContent = '小红猫DPS_v2.3.51';
    text.style.cssText = 'position:absolute; top:18%; left:8%; transform:rotate(-20deg); font-size:42px; font-weight:800; color:#ffffff; opacity:.2;';
    wm.appendChild(text);
    document.body.appendChild(wm);
}
const { ipcRenderer } = require('electron');

// 配置
let settings = {
    opacity: 0.9,
    width: 450,
    height: 500,
    alwaysOnTop: true,
    refreshInterval: 1000, // 减少刷新间隔，提高场景切换响应速度
    combatTimeout: 10000, // 默认10秒战斗超时
    combatTimeoutEnabled: true, // 默认启用战斗超时
    locked: false,
    // UI 个性化设置（仅前端存储）
    fontSize: parseInt(localStorage.getItem('overlay_fontSize') || '12', 10),
    themeColor: localStorage.getItem('overlay_themeColor') || '#e7ae97',
    compactMode: localStorage.getItem('overlay_compact') === '1',
    themeMode: localStorage.getItem('overlay_themeMode') || 'dark'
};

// 排序和显示设置
let displaySettings = {
    sortBy: 'damage', // damage, healing, taken, dps, hps, profession
    // 右侧"伤害值"默认开启；其余默认关闭以满足"只显示秒伤+右侧伤害"的需求
    showDamage: true,
    showHealing: false,
    showTaken: false,
    showProfession: true,
    showCritRate: false,
    showInstantHeal: false,
    showInstantDps: false
};

// 应用条高度与显示密度
function applyDamageSize(size) {
    document.body.classList.remove('size-small', 'size-medium', 'size-large');
    if (size === 'small') {
        document.body.classList.add('size-small');
        // 小：隐藏 mini-bars；禁用设置勾选
        // 不强制设置showHealing，保持用户的选择
        displaySettings.showTaken = false;
        displaySettings.showCritRate = false; // 仅保留秒伤与总伤
        // skill details 紧贴
        const styleElId = 'size-small-overrides';
        let styleEl = document.getElementById(styleElId);
        if (!styleEl) {
            styleEl = document.createElement('style');
            styleEl.id = styleElId;
            styleEl.textContent = `.skill-details{margin-top:1px!important;} .bar-chip{background:transparent;border:0}`;
            document.head.appendChild(styleEl);
        }
        // 设置面板禁用相关选项
        ['showHealingDropdown', 'showTakenDropdown', 'showCritRate', 'showInstantHeal', 'showInstantDps']
            .forEach(id => { const el = document.getElementById(id); if (el) { el.disabled = true; } });
    } else if (size === 'medium') {
        document.body.classList.add('size-medium');
        // 中：允许勾选 mini-bars，默认关闭承伤；允许显示总暴击率
        ['showHealingDropdown', 'showTakenDropdown', 'showCritRate', 'showInstantHeal', 'showInstantDps']
            .forEach(id => { const el = document.getElementById(id); if (el) { el.disabled = false; } });
        // 移除小尺寸覆盖样式
        const el = document.getElementById('size-small-overrides'); if (el) el.remove();
    } else {
        document.body.classList.add('size-large');
        // 大：默认显示 mini-bars 与承伤、总暴击率（但不强制覆盖用户设置）
        // 只在初次设置时应用默认值，不覆盖用户已有的设置
        const sh = document.getElementById('showHealingDropdown');
        const st = document.getElementById('showTakenDropdown');
        const scr = document.getElementById('showCritRate');
        
        // 同步UI状态到displaySettings（而不是强制设置）
        if (sh) displaySettings.showHealing = sh.checked;
        if (st) displaySettings.showTaken = st.checked;
        if (scr) displaySettings.showCritRate = scr.checked;
        ['showHealingDropdown', 'showTakenDropdown', 'showCritRate', 'showInstantHeal', 'showInstantDps']
            .forEach(id => { const el = document.getElementById(id); if (el) { el.disabled = false; } });
        const el = document.getElementById('size-small-overrides'); if (el) el.remove();
    }
    localStorage.setItem('overlay_damageSize', size);

    // 显示通知
    if (size === 'small') {
        showNotification('该模式下无法显示某些数据，如有需要切换其他总体大小', 'warning', 4000);
    } else {
        showNotification(`已切换到${size === 'medium' ? '中等' : '大'}尺寸模式`, 'success', 2000);
    }

    updateDisplay();
}

let refreshTimer = null;
let lastButtonCount = 0; // 追踪按钮数量变化
let updatePaused = false; // 暂停更新标志

// 计时器相关变量
let timerState = {
    isRunning: false,
    duration: 60,
    timeLeft: 60,
    startTime: null,
    timerInterval: null,
    initialData: null
};

// 全局技能点击处理函数
window.handleSkillClick = function (uid) {
    console.log('🎯 全局技能点击函数被调用，UID:', uid);
    if (settings.locked) {
        console.log('窗口已锁定，无法点击');
        alert('窗口已锁定，请先解锁后再操作');
        return;
    }

    const button = document.querySelector(`.skill-btn[data-uid="${uid}"]`);
    if (!button) {
        console.log('未找到对应的按钮元素');
        return;
    }

    console.log('调用togglePlayerSkillDetails，UID:', uid);
    togglePlayerSkillDetails(uid, button);
};

// 初始化应用
async function init() {
    try {
        // 获取当前设置（与本地UI个性化设置合并）
        const nativeSettings = await ipcRenderer.invoke('get-settings');
        settings = { ...settings, ...nativeSettings };
        updateSettingsUI();

        // 初始化时加载昵称数据
        await loadNicknames();

        // 绑定事件
        bindEvents();

        // 初始化自定义快捷键
        initCustomShortcuts();

        // 初始化锁定按钮状态
        initLockButtonState();

        // 初始化网卡配置
        initNetworkDeviceConfig();

        // 同步战斗超时状态
        await syncCombatTimeoutStatus();

        // 验证事件委托绑定
        console.log('🔍 验证事件委托绑定状态:');
        console.log('  - handleGlobalClick函数:', typeof handleGlobalClick);
        console.log('  - 全局点击事件监听器:', document.onclick ? '已绑定' : '未绑定');

        // 开始数据更新
        initSortFromMenu();
        startDataRefresh();

        // 移除定期状态监控，减少场景切换时的请求冲突（参照源码简洁架构）
        // startCaptureStatusCheck();

        // 添加半透明水印
        try { addWatermarkLayer(); } catch { }

        console.log('✅ 悬浮窗初始化完成');
    } catch (error) {
        console.error('初始化失败:', error);
        showError('初始化失败: ' + error.message);
    }
}

// IPv4/IPv6兼容性处理函数
function getApiUrl(endpoint) {
    // 兜底端点列表（优先 IPv4，再 IPv6）
    const ENDPOINTS = [
        `http://127.0.0.1:${settings.apiPort}`,
        `http://[::1]:${settings.apiPort}`
    ];
    
    // 优先使用IPv4地址，避免IPv6解析问题导致的网卡掉线
    const baseUrl = ENDPOINTS[0];
    return baseUrl + endpoint;
}

// 获取所有可用的API端点
function getAllApiEndpoints(endpoint) {
    return [
        `http://127.0.0.1:${settings.apiPort}${endpoint}`,
        `http://[::1]:${settings.apiPort}${endpoint}`
    ];
}

// 网络连接健康检查函数
async function checkNetworkHealth() {
    try {
        // 优先使用IPv4地址检查
        const response = await fetchData(getApiUrl('/api/health'), 0, 3000);
        return response && response.code === 0;
    } catch (error) {
        console.warn('IPv4网络检查失败，尝试IPv6:', error.message);
        
        // IPv4失败时尝试IPv6
        try {
            const ipv6Url = `http://[::1]:${settings.apiPort}/api/health`;
            const ipv6Response = await fetchData(ipv6Url, 0, 3000);
            if (ipv6Response && ipv6Response.code === 0) {
                console.info('✅ IPv6网络检查成功');
                return true;
            }
        } catch (ipv6Error) {
            console.warn('IPv6网络检查也失败:', ipv6Error.message);
        }
        
        return false;
    }
}

// 场景切换优化的GET请求函数
function fetchData(url, retries = 2, timeout = 15000) { // 减少默认超时时间
    return new Promise((resolve, reject) => {
        const attemptRequest = (attempt) => {
            const xhr = new XMLHttpRequest();
            xhr.open('GET', url);
            xhr.timeout = timeout;

            xhr.onload = function () {
                if (xhr.status >= 200 && xhr.status < 300) {
                    try {
                        resolve(JSON.parse(xhr.responseText));
                    } catch (e) {
                        if (attempt < retries) {
                            setTimeout(() => attemptRequest(attempt + 1), 500); // 减少重试间隔到500ms
                        } else {
                            reject(new Error('Invalid JSON response'));
                        }
                    }
                } else {
                    if (attempt < retries && xhr.status >= 500) { // 只对服务器错误重试
                        setTimeout(() => attemptRequest(attempt + 1), 500); // 减少重试间隔
                    } else {
                        reject(new Error(`HTTP ${xhr.status}`));
                    }
                }
            };

            xhr.onerror = () => {
                if (attempt < retries) {
                    setTimeout(() => attemptRequest(attempt + 1), 1000); // 网络错误减少到1秒
                } else {
                    reject(new Error('Network error'));
                }
            };

            xhr.ontimeout = () => {
                if (attempt < retries) {
                    console.log(`⏰ 请求超时，第${attempt + 1}次重试...`);
                    setTimeout(() => attemptRequest(attempt + 1), 1000); // 超时重试减少到1秒
                } else {
                    reject(new Error('Request timeout'));
                }
            };

            xhr.send();
        };

        attemptRequest(0);
    });
}

// 网卡操作专用的POST请求函数
function fetchDataPost(url, data, retries = 1, timeout = 8000) {
    return new Promise((resolve, reject) => {
        const attemptRequest = (attempt) => {
            const xhr = new XMLHttpRequest();
            xhr.open('POST', url);
            xhr.setRequestHeader('Content-Type', 'application/json');
            xhr.timeout = timeout;

            xhr.onload = function () {
                if (xhr.status >= 200 && xhr.status < 300) {
                    try {
                        resolve(JSON.parse(xhr.responseText));
                    } catch (e) {
                        if (attempt < retries) {
                            setTimeout(() => attemptRequest(attempt + 1), 2000);
                        } else {
                            reject(new Error('Invalid JSON response'));
                        }
                    }
                } else {
                    if (attempt < retries && xhr.status >= 500) { // 只对服务器错误重试
                        setTimeout(() => attemptRequest(attempt + 1), 2000);
                    } else {
                        reject(new Error(`HTTP ${xhr.status}`));
                    }
                }
            };

            xhr.onerror = () => {
                if (attempt < retries) {
                    setTimeout(() => attemptRequest(attempt + 1), 3000); // 网卡切换需要更多时间
                } else {
                    reject(new Error('Network error'));
                }
            };

            xhr.ontimeout = () => {
                if (attempt < retries) {
                    setTimeout(() => attemptRequest(attempt + 1), 3000);
                } else {
                    reject(new Error('Request timeout'));
                }
            };

            xhr.send(JSON.stringify(data));
        };

        attemptRequest(0);
    });
}

// 技能按钮点击处理
function handleSkillButtonClick(uid) {
    console.log('🎯 处理技能按钮点击，UID:', uid);
    if (settings.locked) {
        console.log('窗口已锁定，无法点击');
        alert('窗口已锁定，请先解锁后再操作');
        return;
    }

    const button = document.querySelector(`.skill-btn[data-uid="${uid}"]`);
    if (!button) {
        console.log('未找到对应的按钮元素');
        return;
    }

    console.log('调用togglePlayerSkillDetails，UID:', uid);
    togglePlayerSkillDetails(uid, button);
}

// 昵称编辑处理
function handleEditNickname(uid, currentNickname) {
    console.log('🎯 处理昵称编辑，UID:', uid, '当前昵称:', currentNickname);
    // 复用内置的昵称编辑弹窗，避免重复ID冲突
    currentEditingPlayerUid = uid;
    const modal = document.getElementById('nicknameEditModal');
    const uidElement = document.getElementById('editingPlayerUid');
    const nicknameInput = document.getElementById('nicknameInput');
    if (!modal || !uidElement || !nicknameInput) return;
    uidElement.textContent = uid;
    nicknameInput.value = currentNickname || '';
    modal.classList.remove('hidden');
    nicknameInput.focus();
    nicknameInput.select();
}

// 昵称删除处理
async function handleDeleteNickname(uid) {
    console.log('🎯 处理昵称删除，UID:', uid);
    if (confirm(`确定要删除玩家ID ${uid} 的昵称吗？`)) {
        try {
            await saveNicknameInManager(uid, '');
            delete allNicknames[uid];
            // 立即刷新昵称列表显示
            filterNicknames();
            // 同时更新主界面显示
            updateDisplay();
        } catch (error) {
            console.error('删除昵称失败:', error);
        }
    }
}

// 昵称管理处理
function handleManageNicknames() {
    console.log('🎯 处理昵称管理');
    showNicknameManager();
}

// 关闭昵称管理
function handleCloseNicknameManager() {
    console.log('🎯 处理关闭昵称管理');
    hideNicknameManager();
}

// 添加昵称
function handleAddNickname() {
    console.log('🎯 处理添加昵称');
    showAddNicknameDialog();
}

// 刷新昵称
function handleRefreshNicknames() {
    console.log('🎯 处理刷新昵称');
    refreshNicknamesList();
}

// 全局点击处理函数
function handleGlobalClick(e) {
    console.log('🎯 全局点击事件触发:', e.target.tagName, e.target.className, e.target.id);
    console.log('🎯 目标元素:', e.target);
    console.log('🎯 目标元素的classList:', Array.from(e.target.classList));

    // 移除技能按钮点击逻辑（改为点击玩家条）

    // 处理昵称编辑按钮点击
    if (e.target.classList.contains('edit-nickname-item')) {
        e.preventDefault();
        e.stopPropagation();
        const uid = e.target.dataset.uid;
        const nickname = e.target.dataset.nickname;
        console.log('🎯 昵称编辑按钮被点击:', uid, nickname);
        handleEditNickname(uid, nickname);
        return;
    }

    // 处理昵称删除按钮点击
    if (e.target.classList.contains('delete-nickname-item')) {
        e.preventDefault();
        e.stopPropagation();
        const uid = e.target.dataset.uid;
        console.log('🎯 昵称删除按钮被点击:', uid);
        handleDeleteNickname(uid);
        return;
    }

    // 处理昵称管理按钮点击
    if (e.target.id === 'manageNicknames') {
        e.preventDefault();
        e.stopPropagation();
        console.log('🎯 昵称管理按钮被点击');
        handleManageNicknames();
        return;
    }

    // 处理昵称管理弹窗按钮
    if (e.target.id === 'closeNicknameManager') {
        e.preventDefault();
        e.stopPropagation();
        console.log('🎯 关闭昵称管理按钮被点击');
        handleCloseNicknameManager();
        return;
    }

    if (e.target.id === 'addNicknameBtn') {
        e.preventDefault();
        e.stopPropagation();
        console.log('🎯 添加昵称按钮被点击');
        handleAddNickname();
        return;
    }

    if (e.target.id === 'refreshNicknamesBtn') {
        e.preventDefault();
        e.stopPropagation();
        console.log('🎯 刷新昵称按钮被点击');
        handleRefreshNicknames();
        return;
    }
}

// 绑定事件
function bindEvents() {
    // 标题栏按钮
    // 战斗菜单（清空与计时）点击子项后自动关闭
    const combatBtn = document.getElementById('combatBtn');
    const combatMenu = document.getElementById('combatMenu');
    if (combatBtn && combatMenu) {
        combatBtn.addEventListener('click', (e) => {
            e.stopPropagation();
            combatMenu.classList.toggle('show');
        });
        document.addEventListener('click', (e) => {
            if (!e.target.closest('#combatMenu') && !e.target.closest('#combatBtn')) {
                combatMenu.classList.remove('show');
            }
        });
        const clearOption = document.getElementById('combatClearOption');
        if (clearOption) clearOption.addEventListener('click', (e) => { clearServerDataAndUi(); combatMenu.classList.remove('show'); });
        // 历史入口：使用菜单中的"查看历史战斗记录"项
        const historyEntry1 = document.querySelector('#combatMenu .dropdown-header.dropdown-option[tittle="查看历史战斗记录"]');
        const historyEntry2 = document.getElementById('historyEntry');
        const bindHistory = (el) => { if (el) el.addEventListener('click', (e) => { e.stopPropagation(); combatMenu.classList.remove('show'); showHistoryModal(); }); };
        bindHistory(historyEntry1);
        bindHistory(historyEntry2);
        document.querySelectorAll('.combat-timer-option').forEach(el => {
            el.addEventListener('click', (e) => {
                const sec = Number(e.target.getAttribute('data-seconds')) || 60;
                combatMenu.classList.remove('show');
                prepareAndStartTimerWithCountdown(sec);
            });
        });
    }
    document.getElementById('lockBtn').addEventListener('click', toggleLock);

    document.getElementById('settingsBtn').addEventListener('click', toggleSettings);
    document.getElementById('minimizeBtn').addEventListener('click', minimizeWindow);
    document.getElementById('closeBtn').addEventListener('click', closeWindow);

    // 绑定标题栏鼠标事件，支持锁定状态下的交互
    const titleBar = document.getElementById('titleBar');
    if (titleBar) {
        titleBar.addEventListener('mouseenter', handleTitleBarMouseEnterTempDisable);
        titleBar.addEventListener('mouseleave', handleTitleBarMouseLeaveEnable);
    }

    // 使用事件委托处理所有动态元素的点击
    document.addEventListener('click', handleGlobalClick);

    // 监听来自主进程的点击事件
    ipcRenderer.on('skill-button-click', (event, uid) => {
        console.log('收到主进程技能按钮点击事件:', uid);
        handleSkillButtonClick(uid);
    });

    // 全部玩家按钮
    const allBtn = document.getElementById('allBtn');
    if (allBtn) {
        allBtn.addEventListener('click', async () => {
            try {
                await ipcRenderer.invoke('open-all-players');
            } catch (e) {
                console.error('打开全部玩家窗口失败', e);
            }
        });
    }

    ipcRenderer.on('nickname-edit-click', (event, uid, nickname) => {
        console.log('收到主进程昵称编辑点击事件:', uid, nickname);
        handleEditNickname(uid, nickname);
    });

    ipcRenderer.on('nickname-delete-click', (event, uid) => {
        console.log('收到主进程昵称删除点击事件:', uid);
        handleDeleteNickname(uid);
    });

    // 事件委托已绑定，处理所有动态元素点击
    console.log('✅ 事件委托已绑定，处理所有动态元素点击');

    // 键盘快捷键监听器
    document.addEventListener('keydown', handleKeyboardShortcuts);
    console.log('✅ 键盘快捷键监听器已绑定');

    // 全局快捷键监听器（来自主进程）
    ipcRenderer.on('global-shortcut-lock', () => {
        console.log('收到主进程锁定快捷键事件');
        toggleLock();
        showShortcutFeedback(settings.locked ? '窗口已锁定' : '窗口已解锁');
    });

    ipcRenderer.on('global-shortcut-clear-data', () => {
        console.log('收到主进程Ctrl+Shift+R快捷键事件');
        clearServerDataAndUi();
        // 注释掉重复的通知，clearServerDataAndUi()内部已有通知
        // showShortcutFeedback('战斗数据已清空');
    });

    console.log('✅ 全局快捷键监听器已绑定');

    // 设置面板
    document.getElementById('closeSettings').addEventListener('click', hideSettings);

    // 设置控件
    document.getElementById('opacitySlider').addEventListener('input', updateOpacity);
    document.getElementById('widthInput').addEventListener('change', updateSize);
    document.getElementById('heightInput').addEventListener('change', updateSize);
    document.getElementById('alwaysOnTopCheck').addEventListener('change', updateAlwaysOnTop);
    document.getElementById('refreshInterval').addEventListener('change', updateRefreshInterval);
    document.getElementById('combatTimeoutEnabled').addEventListener('change', updateCombatTimeoutEnabled);
    document.getElementById('combatTimeout').addEventListener('change', updateCombatTimeout);
    document.getElementById('resetPosition').addEventListener('click', resetPosition);

    // 网卡配置事件
    const networkDeviceSelect = document.getElementById('networkDeviceSelect');
    const confirmDeviceBtn = document.getElementById('confirmDeviceBtn');

    if (confirmDeviceBtn) {
        confirmDeviceBtn.addEventListener('click', confirmSwitchNetworkDevice);
    }

    // 为下拉菜单添加事件监听器，防止自动关闭
    if (networkDeviceSelect) {
        let dropdownOpen = false;

        networkDeviceSelect.addEventListener('mousedown', () => {
            updatePaused = true;
            dropdownOpen = true;
            // 暂停窗口置顶，给用户足够时间选择网卡
            try { ipcRenderer.invoke('pause-always-on-top', { pause: true, timeoutMs: 15000 }); } catch { }
        });

        networkDeviceSelect.addEventListener('focus', () => {
            // 当下拉框获得焦点时，确保置顶被暂停
            if (dropdownOpen) {
                try { ipcRenderer.invoke('pause-always-on-top', { pause: true, timeoutMs: 15000 }); } catch { }
            }
        });

        networkDeviceSelect.addEventListener('blur', () => {
            updatePaused = false;
            // 延迟恢复置顶，避免下拉框展开期间被强制置顶
            setTimeout(() => {
                if (!dropdownOpen) {
                    try { ipcRenderer.invoke('pause-always-on-top', { pause: false }); } catch { }
                }
            }, 3000);
        });

        networkDeviceSelect.addEventListener('change', () => {
            updatePaused = false;
            dropdownOpen = false;
            // 选择完成后恢复窗口置顶
            try { ipcRenderer.invoke('pause-always-on-top', { pause: false }); } catch { }
        });

        // 监听下拉框的展开状态
        networkDeviceSelect.addEventListener('click', () => {
            if (!dropdownOpen) {
                dropdownOpen = true;
                try { ipcRenderer.invoke('pause-always-on-top', { pause: true, timeoutMs: 15000 }); } catch { }
            }
        });

        // 监听键盘事件，确保ESC键也能正确关闭下拉框
        networkDeviceSelect.addEventListener('keydown', (e) => {
            if (e.key === 'Escape') {
                dropdownOpen = false;
                try { ipcRenderer.invoke('pause-always-on-top', { pause: false }); } catch { }
            }
        });
    }

    // 为战斗超时下拉菜单添加事件监听器
    const combatTimeoutSelect = document.getElementById('combatTimeout');
    if (combatTimeoutSelect) {
        combatTimeoutSelect.addEventListener('mousedown', () => { updatePaused = true; });
        combatTimeoutSelect.addEventListener('blur', () => { updatePaused = false; });
        combatTimeoutSelect.addEventListener('change', () => { updatePaused = false; });
    }

    // 字体与主题
    const fontSizeInput = document.getElementById('fontSizeInput');
    const themeColorInput = document.getElementById('themeColorInput');
    if (fontSizeInput) fontSizeInput.addEventListener('change', updateFontSizeSetting);
    if (themeColorInput) themeColorInput.addEventListener('input', updateThemeColorSetting);
    const compactCheck = document.getElementById('compactModeCheck');
    if (compactCheck) compactCheck.addEventListener('change', updateCompactMode);
    document.querySelectorAll('input[name="themeMode"]').forEach(r => r.addEventListener('change', updateThemeMode));

    // 计时器事件
    document.getElementById('closeTimer').addEventListener('click', hideTimer);

    // 计时器预设按钮
    document.querySelectorAll('.timer-preset').forEach(btn => {
        btn.addEventListener('click', (e) => {
            const time = parseInt(e.target.dataset.time);
            setTimerDuration(time);
        });
    });

    // 自定义时间按钮
    document.getElementById('customStartBtn').addEventListener('click', () => {
        const time = parseInt(document.getElementById('customTime').value);
        if (time >= 10 && time <= 600) {
            setTimerDuration(time);
        } else {
            alert('请输入10-600秒之间的数值');
        }
    });

    // 计时器控制按钮
    document.getElementById('startTimerBtn').addEventListener('click', startTimer);
    document.getElementById('stopTimerBtn').addEventListener('click', stopTimer);
    document.getElementById('resetTimerBtn').addEventListener('click', resetTimer);
    document.getElementById('exitTimerBtn').addEventListener('click', exitTimerMode);

    // 下拉菜单控制
    const controlBtn = document.getElementById('controlBtn');
    const controlMenu = document.getElementById('controlMenu');

    controlBtn.addEventListener('click', (e) => {
        e.stopPropagation();
        controlMenu.classList.toggle('show');
        // 关闭其他下拉菜单
        const combatMenu = document.getElementById('combatMenu');
        if (combatMenu) combatMenu.classList.remove('show');
    });

    // 点击其他地方关闭下拉菜单
    document.addEventListener('click', (e) => {
        if (!e.target.closest('.control-dropdown')) {
            controlMenu.classList.remove('show');
            const combatMenu = document.getElementById('combatMenu');
            if (combatMenu) combatMenu.classList.remove('show');
        }
    });

    // 排序选项，选择后自动关闭菜单
    document.querySelectorAll('input[name="sortBy"]').forEach(radio => {
        radio.addEventListener('change', (e) => {
            if (e.target.checked) {
                setSortMode(e.target.value);
                controlMenu.classList.remove('show');
            }
        });
    });

    // 显示选项移至设置面板，这里不再监听被移除的下拉勾选项

    // 返回按钮
    const backBtn = document.getElementById('backBtn');
    if (backBtn) backBtn.addEventListener('click', showMainView);

    // 昵称编辑功能
    const editNicknameBtn = document.getElementById('editNicknameBtn');
    const closeNicknameModalBtn = document.getElementById('closeNicknameModal');
    const cancelNicknameBtn = document.getElementById('cancelNicknameBtn');
    const saveNicknameBtn = document.getElementById('saveNicknameBtn');
    if (editNicknameBtn) {
        editNicknameBtn.onclick = (e) => { e.stopPropagation(); showNicknameEditModal(); };
    }
    if (closeNicknameModalBtn) closeNicknameModalBtn.onclick = hideNicknameEditModal;
    if (cancelNicknameBtn) cancelNicknameBtn.onclick = hideNicknameEditModal;
    if (saveNicknameBtn) saveNicknameBtn.onclick = savePlayerNickname;

    // 昵称管理功能
    const searchEl = document.getElementById('nicknameSearch');
    if (searchEl) searchEl.addEventListener('input', filterNicknames);
    const manageBtn = document.getElementById('manageNicknames');
    if (manageBtn) manageBtn.addEventListener('click', showNicknameManager);
    const closeManagerBtn = document.getElementById('closeNicknameManager');
    if (closeManagerBtn) closeManagerBtn.addEventListener('click', hideNicknameManager);
    const addNicknameBtn = document.getElementById('addNicknameBtn');
    if (addNicknameBtn) addNicknameBtn.addEventListener('click', showAddNicknameDialog);

    // 历史记录功能
    const historyBtn = document.getElementById('historyBtn');
    if (historyBtn) historyBtn.addEventListener('click', showHistoryModal);
    const closeHistoryBtn = document.getElementById('closeHistory');
    if (closeHistoryBtn) closeHistoryBtn.addEventListener('click', hideHistoryModal);
    const refreshHistoryBtn = document.getElementById('refreshHistory');
    if (refreshHistoryBtn) refreshHistoryBtn.addEventListener('click', loadHistoryList);
    const clearAllHistoryBtn = document.getElementById('clearAllHistory');
    if (clearAllHistoryBtn) clearAllHistoryBtn.addEventListener('click', clearAllHistory);
    const closeHistoryDetailBtn = document.getElementById('closeHistoryDetail');
    if (closeHistoryDetailBtn) closeHistoryDetailBtn.addEventListener('click', hideHistoryDetail);

    // 键盘快捷键
    document.addEventListener('keydown', handleKeyboardShortcuts);

    // 显示模式与显示区域开关
    ['showDamageDropdown', 'showHealingDropdown', 'showTakenDropdown', 'showProfessionDropdown', 'showCritRate', 'showInstantHeal', 'showInstantDps']
        .forEach(id => {
            const el = document.getElementById(id);
            if (el) el.addEventListener('change', updateDisplaySettings);
        });

    // 伤害总体大小（条高度）
    document.querySelectorAll('input[name="damageSize"]').forEach(r => {
        r.addEventListener('change', () => {
            if (!r.checked) return;
            applyDamageSize(r.value);
        });
    });

    // 当打开刷新间隔下拉时，暂停渲染，关闭时恢复
    const refreshSelect = document.getElementById('refreshInterval');
    if (refreshSelect) {
        refreshSelect.addEventListener('mousedown', () => { updatePaused = true; });
        refreshSelect.addEventListener('blur', () => { updatePaused = false; });
        refreshSelect.addEventListener('change', () => { updatePaused = false; });
    }



    // 汇总显示勾选已迁移至设置面板
}

// 获取伤害数据
let lastFetchedUserMap = null; // 记录最近一次数据用于汇总刷新
async function fetchDamageData() {
    try {
        // 场景切换优化：使用智能重试和快速超时
        // 使用统一的API地址函数，避免IPv4/IPv6解析问题
        const data = await fetchData(getApiUrl('/api/data'), 1, 8000);
        if (data.code !== 0) {
            throw new Error(data.msg || '服务器返回错误');
        }
        lastFetchedUserMap = data.user || {};
        return lastFetchedUserMap;
    } catch (error) {
        console.error('获取数据失败:', error);

        // 优化的场景切换恢复机制 - 快速响应
        if (error.message.includes('Request timeout') || error.message.includes('Network error')) {
            console.info('🔄 场景切换或网络波动，尝试IPv4/IPv6切换恢复...');
            
            // 尝试IPv4/IPv6端点切换
            const endpoints = getAllApiEndpoints('/api/data');
            for (const endpoint of endpoints) {
                try {
                    console.log(`🔄 尝试端点: ${endpoint}`);
                    const retryData = await fetchData(endpoint, 0, 5000);
                    if (retryData.code === 0) {
                        console.info(`✅ 端点切换成功: ${endpoint}`);
                        lastFetchedUserMap = retryData.user || {};
                        return lastFetchedUserMap;
                    }
                } catch (endpointError) {
                    console.warn(`❌ 端点失败: ${endpoint}`, endpointError.message);
                }
            }
            
            // 如果端点切换都失败，进行传统重试
            console.info('🔄 端点切换失败，进行传统重试...');
            for (let retryCount = 1; retryCount <= 3; retryCount++) {
                const waitTime = retryCount * 500; // 500ms、1秒、1.5秒
                console.log(`⏳ 第${retryCount}次重试等待${waitTime/1000}秒...`);
                
                await new Promise(resolve => setTimeout(resolve, waitTime));
                
                try {
                    // 使用IPv4地址，避免IPv6解析问题
                    const retryData = await fetchData(getApiUrl('/api/data'), 0, 10000);
                    if (retryData.code === 0) {
                        console.info(`✅ 第${retryCount}次重试成功，网络已恢复`);
                        lastFetchedUserMap = retryData.user || {};
                        return lastFetchedUserMap;
                    }
                } catch (retryError) {
                    console.warn(`❌ 第${retryCount}次重试失败:`, retryError.message);
                    if (retryCount === 3) {
                        console.error('❌ 所有重试都失败了');
                    }
                }
            }
        }

        throw error;
    }
}

// 上次数据的哈希值，用于检测数据是否真的变化了
let lastDataHash = '';
let hadDataBefore = false; // 用于检测自动清空

// 更新连接状态显示 - 简化版
function updateConnectionStatus(status, message = '') {
    const connectionStatus = document.getElementById('connectionStatus');
    const reconnectBtn = document.getElementById('reconnectBtn');
    
    if (!connectionStatus || !reconnectBtn) return;
    
    switch (status) {
        case 'connected':
            connectionStatus.style.display = 'none';
            break;
        case 'connecting':
            connectionStatus.style.display = 'none';
            break;
        case 'error':
            connectionStatus.style.display = 'flex';
            break;
        default:
            connectionStatus.style.display = 'none';
    }
}

// 更新显示数据
async function updateDisplay() {
    // 1) 恢复：当有技能详情展开时，暂停数据刷新，避免抖动
    if (updatePaused || document.querySelector('.damage-item.expanded .skill-details')) {
        //console.log('⏸ 技能详情展开中，暂停刷新');
        return;
    }

    // 2) 新增：当设置面板打开时，暂停数据刷新，避免下拉框被关闭
    const settingsPanel = document.getElementById('settingsPanel');
    if (settingsPanel && !settingsPanel.classList.contains('hidden')) {
        //console.log('⏸ 设置面板打开中，暂停刷新');
        return;
    }

    const damageList = document.getElementById('damageList');
    
    // 更新连接状态为连接中
            updateConnectionStatus('connecting');

    try {
        const userData = await fetchDamageData();

        if (Object.keys(userData).length === 0) {
            // 检测是否是自动清空：之前有数据，现在突然没有数据了
            if (hadDataBefore && lastDataHash !== '') {
                console.log('🔍 检测到数据被自动清空');
                showNotification('战斗数据已保存', 'success', 3000);
                hadDataBefore = false;
            }
            damageList.innerHTML = '<div class="loading"> 暂无数据</div>';
            lastDataHash = '';
            return;
        }

        // 标记现在有数据了
        hadDataBefore = true;

        // 检查数据是否真的变化了（防止无意义的DOM重建）
        const currentDataHash = JSON.stringify(userData);
        if (currentDataHash === lastDataHash) {
            console.log(' 数据未变化，跳过更新');
            return;
        }
        lastDataHash = currentDataHash;

        // 转换为数组并排序，优化昵称获取逻辑
        const players = Object.keys(userData).map(uid => {
            const user = userData[uid];
            // 优先级：本地存储的昵称 > 服务器返回的昵称 > 服务器返回的名称 > 默认UID格式
            let nickname = user.nickname || user.name || `玩家_${uid}`;

            // 如果有本地存储的昵称，使用本地的
            if (allNicknames && allNicknames[uid]) {
                nickname = allNicknames[uid];
            }

            return {
                uid: uid,
                nickname: nickname,
                ...user
            };
        });

        console.log('📊 数据已变化，开始更新 - 玩家数量:', players.length);
        
        // 更新连接状态为已连接
        updateConnectionStatus('connected');

        // 根据当前排序模式排序
        sortPlayers(players);

        // 计算百分比（第一名为100%），根据当前排序类型确定最大值
        let maxValue = 1;
        if (players.length > 0) {
            switch (displaySettings.sortBy) {
                case 'damage':
                    maxValue = players[0].total_damage.total;
                    break;
                case 'healing':
                    const normalizedFirstPlayerHealing = normalizeHealingData(players[0]);
                    maxValue = normalizedFirstPlayerHealing ? normalizedFirstPlayerHealing.total : 1;
                    break;
                case 'taken':
                    maxValue = players[0].taken_damage || 1;
                    break;
                case 'dps':
                    maxValue = players[0].total_dps || 1;
                    break;
                case 'instant':
                    maxValue = players[0].realtime_dps || players[0].realtime_dps_value || 1;
                    break;
                case 'hps':
                    maxValue = players[0].total_hps || 1;
                    break;
                default:
                    maxValue = players[0].total_damage.total;
                    break;
            }
        }

        // 增加玩家条高度后，默认展示数量适当提升，仍给紧凑模式更多可视数量
        const maxVisible = settings.compactMode ? 20 : 20;
        const visiblePlayers = players.slice(0, maxVisible);

        // 总览柱状图更新（根据勾选显示）
        updateOverviewBars(userData);

        // 先清空列表
        damageList.innerHTML = '';

        // 使用DOM操作而不是innerHTML（可能解决Electron问题）
        visiblePlayers.forEach((player, index) => {
            const rank = index + 1;

            // 根据当前排序类型计算百分比
            let currentValue = 0;
            let percentage = 0;
            switch (displaySettings.sortBy) {
                case 'damage':
                    currentValue = player.total_damage.total;
                    break;
                case 'healing':
                    const normalizedPlayerHealing = normalizeHealingData(player);
                    currentValue = normalizedPlayerHealing ? normalizedPlayerHealing.total : 0;
                    break;
                case 'taken':
                    currentValue = player.taken_damage || 0;
                    break;
                case 'dps':
                    currentValue = player.total_dps || 0;
                    break;
                case 'instant':
                    currentValue = player.realtime_dps || player.realtime_dps_value || player.realtime_dps_max || 0;
                    break;
                case 'hps':
                    currentValue = player.total_hps || 0;
                    break;
                default:
                    currentValue = player.total_damage.total;
                    break;
            }

            // 统一处理治疗数据（确保数据结构一致性）
            const normalizedHealing = normalizeHealingData(player);
            const hasHealing = normalizedHealing && normalizedHealing.total > 0;
            const healingData = hasHealing ? normalizedHealing : null;
            const healingDps = hasHealing ? (player.total_hps || 0).toFixed(0) : '0';

            // 处理承受伤害（如果有）
            const takenDamage = player.taken_damage || 0;

            // 计算百分比，避免除零和无限大值
            const calculatePercentage = (value, maxValue) => {
                if (!maxValue || maxValue <= 0) return 0;
                const percentage = Math.round((value / maxValue) * 100);
                return Math.min(percentage, 100); // 限制最大值为100%
            };

            // 在updateDisplay函数中使用
            const damagePercentage = calculatePercentage(currentValue, maxValue);
            const healingPercentage = hasHealing ? calculatePercentage(healingData.total, maxValue) : 0;
            const takenPercentage = (takenDamage > 0) ? calculatePercentage(takenDamage, maxValue) : 0;

            percentage = maxValue > 0 ? Math.round((currentValue / maxValue) * 100) : 0;
            const critRate = ((player.total_count.critical / player.total_count.total) * 100).toFixed(1);
            const luckyRate = ((player.total_count.lucky / player.total_count.total) * 100).toFixed(1);

            // 获取职业信息
            const profession = player.profession || '未知';

            // 获取职业颜色信息
            const professionColor = getProfessionColor(profession);

            // 创建玩家项目DOM元素
            const damageItem = document.createElement('div');
            damageItem.className = 'damage-item';
            damageItem.setAttribute('data-uid', player.uid);
            // 设置职业颜色样式
            damageItem.style.borderLeft = `1px solid ${professionColor.border}`;
            damageItem.style.background = `linear-gradient(135deg, ${professionColor.bg}15 0%, rgba(255, 255, 255, 0.08) 100%)`;

            // 创建玩家信息 - 使用网格布局固定对齐
            const playerInfo = document.createElement('div');
            // playerInfo.className = 'player-info compact';



            // 3. 顶部百分比移除：避免与条内重复，不在条上方再展示

            damageItem.appendChild(playerInfo);

            // 创建伤害主要信息
            const damageMain = document.createElement('div');
            damageMain.className = 'damage-main';
            // 顶部冗余信息已移除：不再在条外重复展示职业/昵称/百分比

            const percentageBar = document.createElement('div');
            percentageBar.className = 'percentage-bar';
            // 使用职业颜色作为柱状图颜色
            const barColor = professionColor.bg;
            percentageBar.innerHTML = `
                <div class="percentage-fill" style="width: ${percentage}%; background: linear-gradient(90deg, ${barColor}, ${professionColor.border}) !important;"></div>
                <div class="bar-overlay">
                    <div class="bar-left">
                        <div class="identity">
                            ${displaySettings.showProfession ? `<span class=\"profession-badge small\" style=\"background:${professionColor.bg}\">${profession}</span>` : ''}
                            <span class="nickname" title="${player.nickname || player.name || player.uid}">${player.nickname || player.name || ('玩家_' + player.uid)}</span>
                        </div>
                        <div class="under-metrics">
                            ${displaySettings.showHealing && hasHealing ? `<div class=\"mini-bar\"><div class=\"fill heal\" style=\"width:${healingPercentage}%\"></div></div>` : ''}
                            ${displaySettings.showTaken && (takenDamage > 0) ? `<div class=\"mini-bar\"><div class=\"fill taken\" style=\"width:${takenPercentage}%\"></div></div>` : ''}
                        </div>
                    </div>
                    <div class="bar-center">
                       
                        <span class="bar-chip dps-chip fixed-dps">${formatWan(player.total_dps)}/秒</span>
                        ${displaySettings.showCritRate ? `<span class=\"bar-chip crit\">暴 ${critRate}%</span>` : ''}
                        ${displaySettings.showInstantDps && player.instant_dps ? `<span class=\"bar-chip instant\">瞬 ${player.instant_dps.toFixed(0)}</span>` : ''}
                        ${displaySettings.showInstantHeal && player.instant_hps ? `<span class=\"bar-chip instant-heal\">疗 ${player.instant_hps.toFixed(0)}</span>` : ''}
                    </div>
                    ${displaySettings.showDamage ? `<div class=\"bar-right\"><span class=\"bar-right-value\">${formatNumber(currentValue)}</span> <span class=\"percent-sup\">${percentage}%</span></div>` : ''}
                </div>`;
            // 点击进度条区域也能展开技能详情
            percentageBar.addEventListener('click', (e) => {
                e.stopPropagation();
                togglePlayerSkillDetailsByItem(player.uid, damageItem);
            });
            damageMain.appendChild(percentageBar);



            damageItem.appendChild(damageMain);

            // 点击区域迁移：仅在 damage-main 内点击才展开技能详情
            damageItem.addEventListener('click', (e) => { e.stopPropagation(); });
            damageMain.addEventListener('click', (e) => {
                if (settings.locked) return;
                e.stopPropagation();
                togglePlayerSkillDetailsByItem(player.uid, damageItem);
            });

            // 创建技能详情区域
            const skillDetails = document.createElement('div');
            skillDetails.className = 'skill-details';
            skillDetails.id = `skill-${player.uid}`;
            skillDetails.style.display = 'none';
            skillDetails.innerHTML = '<div class="skill-loading">加载技能数据中...</div>';

            damageItem.appendChild(skillDetails);

            // 添加到列表
            damageList.appendChild(damageItem);
        });

        // 事件委托已在初始化时绑定，无需重复绑定

        // 更新完成后，确保透明度正确应用到新创建的元素
        if (settings.opacity) {
            updateElementsOpacity(settings.opacity);
        }

    } catch (error) {
        console.error('更新显示失败:', error);
        
        // 根据错误类型提供更友好的提示
        let errorMessage = '';
        if (error.message.includes('Request timeout')) {
            errorMessage = '连接超时，正在重试中...';
        } else if (error.message.includes('Network error')) {
            errorMessage = '网络连接异常，正在重试中...';
        } else if (error.message.includes('HTTP 500')) {
            errorMessage = '服务器内部错误，请稍后重试';
        } else {
            errorMessage = `连接失败: ${error.message}`;
        }
        
        // 更新连接状态为错误
        updateConnectionStatus('error');
        
        damageList.innerHTML = `<div class="loading">🔄 ${errorMessage}</div>`;
        
        // 显示通知提示
        showNotification(errorMessage, 'warning', 5000);
    }
}

// 直接点击处理函数（全局函数，供onclick调用）
window.handleSkillButtonDirectClick = function (uid, button) {
    console.log('直接点击处理函数被调用，UID:', uid);
    console.log('按钮元素:', button);
    console.log('锁定状态:', settings.locked);

    if (settings.locked) {
        console.log('窗口已锁定，无法点击');
        alert('窗口已锁定，请先解锁后再操作');
        return;
    }

    if (button.disabled) {
        console.log('按钮已禁用，不执行操作');
        return;
    }

    console.log('调用togglePlayerSkillDetails，UID:', uid);
    togglePlayerSkillDetails(uid, button);
};

// 切换玩家技能详情展开/收起
async function togglePlayerSkillDetails(uid, button) {
    console.log('togglePlayerSkillDetails调用，UID:', uid);

    const skillDetailsDiv = document.getElementById(`skill-${uid}`);
    if (!skillDetailsDiv) {
        alert(`❌ 错误：找不到技能详情容器\nID: skill-${uid}`);
        return;
    }

    const isExpanded = skillDetailsDiv.style.display !== 'none';
    console.log('当前展开状态:', isExpanded);

    if (isExpanded) {
        // 收起
        skillDetailsDiv.style.display = 'none';
        const damageItem = button.closest('.damage-item');
        if (damageItem) damageItem.classList.remove('expanded');
    } else {
        // 展开
        skillDetailsDiv.style.display = 'block';
        const damageItem = button.closest('.damage-item');
        if (damageItem) damageItem.classList.add('expanded');
        
        // 检查是否已有技能数据，如果有且不是错误状态则不重新加载
        const hasValidData = skillDetailsDiv.querySelector('.skill-details-content') && 
                            !skillDetailsDiv.querySelector('.skill-error') && 
                            !skillDetailsDiv.querySelector('.skill-loading');
        
        if (!hasValidData) {
            // 只有在没有有效数据时才重新加载
            try { 
                await loadPlayerSkillData(uid, skillDetailsDiv); 
            } catch (error) { 
                console.error('技能数据加载失败:', error); 
            }
        }
    }
}

// 通过玩家条 DOM 切换展开
async function togglePlayerSkillDetailsByItem(uid, damageItem) {
    const skillDetailsDiv = document.getElementById(`skill-${uid}`);
    if (!skillDetailsDiv) return;
    const isExpanded = skillDetailsDiv.style.display !== 'none';
    if (isExpanded) {
        skillDetailsDiv.style.display = 'none';
        damageItem.classList.remove('expanded');
    } else {
        skillDetailsDiv.style.display = 'block';
        damageItem.classList.add('expanded');
        
        // 检查是否已有技能数据，如果有且不是错误状态则不重新加载
        const hasValidData = skillDetailsDiv.querySelector('.skill-details-content') && 
                            !skillDetailsDiv.querySelector('.skill-error') && 
                            !skillDetailsDiv.querySelector('.skill-loading');
        
        if (!hasValidData) {
            // 只有在没有有效数据时才重新加载
            try { 
                await loadPlayerSkillData(uid, skillDetailsDiv); 
            } catch (e) { 
                console.error(e); 
            }
        }
    }
}

// 加载玩家技能数据
async function loadPlayerSkillData(uid, container) {
    console.log('加载玩家技能数据，UID:', uid);

    try {
        container.innerHTML = '<div class="skill-loading">🔄 加载技能数据中...</div>';

        // 根据当前排序类型传递排序参数（修复技能筛选显示逻辑）
        let sortParam = '';
        if (displaySettings.sortBy === 'healing') {
            sortParam = '?sort=healing';
        } else if (displaySettings.sortBy === 'taken') {
            sortParam = '?sort=taken';
        } else {
            sortParam = '?sort=damage'; // 默认按伤害排序
        }

        const response = await fetchData(getApiUrl(`/api/skill-stats/${uid}${sortParam}`));

        if (response.code === 0 && response.data && response.data.length > 0) {
            renderSkillDetails(response.data, container, uid);
        } else {
            container.innerHTML = '<div class="skill-error">暂无技能数据</div>';
        }
    } catch (error) {
        console.error('加载技能数据时出错:', error);
        container.innerHTML = '<div class="skill-error">❌ 加载失败: ' + error.message + '</div>';
    }
}

// 渲染技能详情
function renderSkillDetails(skillData, container, uid) {
    console.log('渲染技能详情，UID:', uid, '数据:', skillData);

    let html = '<div class="skill-details-content">';

    if (skillData && skillData.length > 0) {
        // 添加表头
        html += `
            <div class="skill-header-row">
                <div class="skill-header-name">技能名称</div>
                <div class="skill-header-damage">伤害/治疗</div>
                <div class="skill-header-count">次数</div>
                <div class="skill-header-crit">暴击</div>
                <div class="skill-header-percentage">占比</div>
            </div>
        `;

        // 渲染技能条目
        skillData.forEach((skill) => {
            const percentage = Math.max(parseFloat(skill.percentage) || 0, 0);
            const name = skill.skill_name || `技能${skill.skill_id}`;
            const damage = skill.total_damage || 0;
            const count = skill.count || 0;
            const skillType = skill.skill_type || 'damage';

            // 根据技能类型确定样式
            let skillItemClass = 'skill-item';
            let barColor = '#c00d07'; // 默认伤害技能颜色

            switch (skillType) {
                case 'healing':
                    skillItemClass += ' skill-healing';
                    barColor = '#2ecc71'; // 绿色表示治疗
                    break;
                case 'taken':
                    skillItemClass += ' skill-taken';
                    barColor = '#95a5a6'; // 灰白色表示承伤
                    break;
                case 'mixed':
                    skillItemClass += ' skill-mixed';
                    barColor = '#f39c12'; // 橙色表示复合技能
                    break;
                default:
                    skillItemClass += ' skill-damage';
                    barColor = '#c00d07'; // 红色表示伤害
                    break;
            }

            const critRate = skill.crit_rate || '0.0';

            html += `
                <div class="${skillItemClass}">
                    <div class="skill-line">
                        <div class="skill-col-name" title="${name}">${name}</div>
                        <div class="skill-col-damage">${formatNumber(damage)}</div>
                        <div class="skill-col-count">${count}次</div>
                        <div class="skill-col-crit">${critRate}%</div>
                        <div class="skill-col-percentage">${percentage.toFixed(1)}%</div>
                    </div>
                    <div class="skill-bar-row">
                        <div class="skill-bar-fill" style="width: ${Math.max(percentage, 2)}%; background: ${barColor} !important;"></div>
                    </div>
                </div>
            `;
        });
    } else {
        html += '<div class="skill-empty">📭 暂无技能数据</div>';
    }

    html += '</div>';
    container.innerHTML = html;
}

// 事件绑定检查函数已不再需要，因为使用了onclick直接绑定

// 职业颜色映射 - 根据属性重新配置颜色（已暗化处理）
const PROFESSION_COLORS = {
    // 雷影剑士
    '雷影剑士': { bg: '#663399', border: '#552288', name: '雷影剑士' },
    '居合': { bg: '#663399', border: '#552288', name: '居合' },
    '居合流': { bg: '#663399', border: '#552288', name: '居合流' },
    '雷影剑士-居合流': { bg: '#663399', border: '#552288', name: '雷影剑士-居合流' },
    '月刃': { bg: '#5a4fcf', border: '#4a3fb5', name: '月刃' },

    // 青岚骑士
    '青岚骑士': { bg: '#008866', border: '#007755', name: '青岚骑士' },
    '重装': { bg: '#008866', border: '#007755', name: '重装' },
    '空战': { bg: '#008866', border: '#007755', name: '空战' },
    '空枪': { bg: '#008866', border: '#007755', name: '空枪' },

    // 神射手
    '神射手': { bg: '#cc7700', border: '#bb6600', name: '神射手' },
    '鹰弓': { bg: '#cc7700', border: '#bb6600', name: '鹰弓' },
    '狼弓': { bg: '#cc9900', border: '#bb8800', name: '狼弓' },

    // 冰魔导师
    '冰魔导师': { bg: '#2277aa', border: '#1a6688', name: '冰魔导师' },
    '冰矛': { bg: '#2277aa', border: '#1a6688', name: '冰矛' },
    '射线': { bg: '#4488bb', border: '#3377aa', name: '射线' },

    // 森语者
    '森语者': { bg: '#1a7744', border: '#155533', name: '森语者' },
    '惩击': { bg: '#1a7744', border: '#155533', name: '惩击' },
    '愈合': { bg: '#229955', border: '#1a7744', name: '愈合' },

    // 巨刃守护者
    '巨刃守护者': { bg: '#663311', border: '#552200', name: '巨刃守护者' },
    '岩盾': { bg: '#663311', border: '#552200', name: '岩盾' },
    '格挡': { bg: '#773322', border: '#663311', name: '格挡' },

    // 神盾骑士
    '神盾骑士': { bg: '#cc5500', border: '#aa4400', name: '神盾骑士' },
    '防回': { bg: '#cc5500', border: '#aa4400', name: '防回' },
    '光盾': { bg: '#dd6600', border: '#cc5500', name: '光盾' },

    // 灵魂乐手
    '灵魂乐手': { bg: '#cc2200', border: '#aa1100', name: '灵魂乐手' },
    '协奏': { bg: '#cc2200', border: '#aa1100', name: '协奏' },
    '狂音': { bg: '#dd3344', border: '#cc2233', name: '狂音' },

    // 其他/未知职业
    '未知': { bg: '#6c7077', border: '#5a5f65', name: '未知' }      // 默认灰色（已暗化）
};

// 获取职业颜色信息
function getProfessionColor(profession) {
    return PROFESSION_COLORS[profession] || PROFESSION_COLORS['未知'];
}

// 格式化数字
function formatNumber(num) {
    if (num >= 10000) {
        return (num / 10000).toFixed(1) + '万';
    }
    return num.toString();
}

// 统一治疗数据结构，解决新旧系统并存问题
function normalizeHealingData(player) {
    if (!player) return null;
    
    // 优先使用标准的 total_healing.total 结构
    if (player.total_healing && typeof player.total_healing === 'object' && player.total_healing.total !== undefined) {
        return player.total_healing;
    }
    
    // 兼容旧系统：如果 total_healing 是数字，转换为标准结构
    if (typeof player.total_healing === 'number') {
        console.warn('检测到旧格式的治疗数据，正在转换为标准格式:', player.total_healing);
        return {
            total: player.total_healing,
            // 可能的其他字段可以在这里添加
        };
    }
    
    // 检查是否有其他可能的治疗数据字段
    if (player.healing && typeof player.healing === 'number') {
        console.warn('检测到非标准治疗数据字段，正在转换:', player.healing);
        return {
            total: player.healing,
        };
    }
    
    // 没有治疗数据
    return null;
}

// 始终以"万"为单位格式化（用于秒伤等），不足一万时显示0.x万
function formatWan(num) {
    const v = (Number(num) || 0) / 10000;
    return v.toFixed(1) + '万';
}

// 总览柱状图渲染
function updateOverviewBars(userMap) {
    try {
        const totals = { damage: 0, healing: 0, taken: 0 };
        Object.keys(userMap).forEach(uid => {
            const u = userMap[uid] || {};
            totals.damage += (u.total_damage?.total || 0);
            const normalizedHealing = normalizeHealingData(u);
            totals.healing += normalizedHealing ? normalizedHealing.total : 0;
            totals.taken += (u.taken_damage || 0);
        });
        const showSummaryDamage = document.getElementById('showSummaryDamage')?.checked ?? true;
        const showSummaryHealing = document.getElementById('showSummaryHealing')?.checked ?? true;
        const showSummaryTaken = document.getElementById('showSummaryTaken')?.checked ?? false;

        // 依据勾选项决定参与比较的最大值
        const candidate = [];
        if (showSummaryDamage) candidate.push(totals.damage);
        if (showSummaryHealing) candidate.push(totals.healing);
        if (showSummaryTaken) candidate.push(totals.taken);
        const maxAll = Math.max(...(candidate.length ? candidate : [1]));

        // 总伤害
        const dmgRow = document.querySelector('#overviewDamage')?.closest('.overview-row');
        if (dmgRow) dmgRow.style.display = showSummaryDamage ? '' : 'none';
        const dmgEl = document.querySelector('#overviewDamage');
        if (dmgEl) dmgEl.textContent = formatNumber(totals.damage);
        const dmgFill = document.querySelector('.overview-fill.damage');
        if (dmgFill) dmgFill.style.width = `${Math.round((totals.damage / maxAll) * 100)}%`;
        // 总治疗
        const healRow = document.querySelector('#overviewHealing')?.closest('.overview-row');
        if (healRow) healRow.style.display = showSummaryHealing ? '' : 'none';
        const healEl = document.querySelector('#overviewHealing');
        if (healEl) healEl.textContent = formatNumber(totals.healing);
        const healFill = document.querySelector('.overview-fill.healing');
        if (healFill) healFill.style.width = `${Math.round((totals.healing / maxAll) * 100)}%`;
        // 总承伤
        const takenRow = document.querySelector('#overviewTaken')?.closest('.overview-row');
        if (takenRow) takenRow.style.display = showSummaryTaken ? '' : 'none';
        const takenEl = document.querySelector('#overviewTaken');
        if (takenEl) takenEl.textContent = formatNumber(totals.taken);
        const takenFill = document.querySelector('.overview-fill.taken');
        if (takenFill) takenFill.style.width = `${Math.round((totals.taken / maxAll) * 100)}%`;
    } catch (e) {
        console.warn('updateOverviewBars error', e);
    }
}

// 显示错误
function showError(message) {
    const damageList = document.getElementById('damageList');
    damageList.innerHTML = `<div class="loading">❌ ${message}</div>`;
}

// 开始数据刷新
function startDataRefresh() {
    // 立即更新一次
    updateDisplay();

    // 清除现有定时器
    if (refreshTimer) {
        clearInterval(refreshTimer);
    }

    // 设置新的定时器
    refreshTimer = setInterval(updateDisplay, settings.refreshInterval);
}

// 战斗时长刷新与动画
let durationTimer = null;
async function startDurationTicker() {
    if (durationTimer) clearInterval(durationTimer);
    durationTimer = setInterval(async () => {
        try {
            const resp = await fetchData(getApiUrl('/api/combat-duration'));
            const sec = Number(resp?.duration || 0);
            const mm = Math.floor(sec / 60).toString();
            const ss = (sec % 60).toString().padStart(2, '0');
            const el = document.getElementById('battleDurationToast');
            const text = document.getElementById('battleDurationText');
            if (el && text) {
                const label = isTimerBattleMode ? '计时战斗' : '战斗时长';
                text.textContent = `${label} ${mm}:${ss}`;
                // 简化样式：不增大字号，不位移，只在计时中使用斜体+加粗
                if (isTimerBattleMode) {
                    text.style.fontStyle = 'italic';
                    text.style.fontWeight = '800';
                } else {
                    text.style.fontStyle = '';
                    text.style.fontWeight = '';
                }
                if (sec > 0) {
                    el.classList.remove('hidden');
                    el.classList.add('show');
                } else {
                    el.classList.remove('show');
                    el.classList.add('hidden');
                }
            }
        } catch (_) { }
    }, 1000);
}

// 启动时长刷新
document.addEventListener('DOMContentLoaded', () => {
    startDurationTicker();
    
                // 初始化连接状态 - 隐藏连接状态区域
            updateConnectionStatus('connecting');
    
    // 绑定重连按钮事件
    const reconnectBtn = document.getElementById('reconnectBtn');
    if (reconnectBtn) {
                            reconnectBtn.addEventListener('click', async () => {
                        console.log('🔄 用户点击重连按钮');
                        updateConnectionStatus('connecting');
                        
                        try {
                            // 等待一下再重试，避免立即失败
                            await new Promise(resolve => setTimeout(resolve, 1000));
                            
                            // 强制刷新数据
                            await updateDisplay();
                            
                            console.log('✅ 重连成功');
                        } catch (error) {
                            console.error('❌ 重连失败:', error);
                            updateConnectionStatus('error');
                        }
                    });
    }
});

// 停止数据刷新
function stopDataRefresh() {
    if (refreshTimer) {
        clearInterval(refreshTimer);
        refreshTimer = null;
    }
}

// 设置面板相关函数
function toggleSettings() {
    const panel = document.getElementById('settingsPanel');
    panel.classList.toggle('hidden');

    // 如果处于锁定状态，需要为设置面板添加鼠标事件
    if (settings.locked) {
        if (!panel.classList.contains('hidden')) {
            // 设置面板打开时，禁用穿透
            ipcRenderer.invoke('set-click-through', false);
            panel.addEventListener('mouseenter', handleSettingsPanelMouseEnter);
            panel.addEventListener('mouseleave', handleSettingsPanelMouseLeave);
        } else {
            // 设置面板关闭时，移除事件监听器并恢复穿透
            panel.removeEventListener('mouseenter', handleSettingsPanelMouseEnter);
            panel.removeEventListener('mouseleave', handleSettingsPanelMouseLeave);
            ipcRenderer.invoke('set-click-through', true);
        }
    }
    // 无论锁定与否，打开设置面板时暂停窗口自动置顶心跳，避免DOM交互被抢焦
    if (!panel.classList.contains('hidden')) {
        try { ipcRenderer.invoke('pause-always-on-top', { pause: true, timeoutMs: 15000 }); } catch { }
    } else {
        try { ipcRenderer.invoke('pause-always-on-top', false); } catch { }
    }
}

function hideSettings() {
    const panel = document.getElementById('settingsPanel');
    panel.classList.add('hidden');

    // 如果处于锁定状态，需要恢复穿透并移除事件监听器
    if (settings.locked) {
        panel.removeEventListener('mouseenter', handleSettingsPanelMouseEnter);
        panel.removeEventListener('mouseleave', handleSettingsPanelMouseLeave);
        ipcRenderer.invoke('set-click-through', true);
    }
    try { ipcRenderer.invoke('pause-always-on-top', false); } catch { }
}

// 设置面板鼠标事件处理
function handleSettingsPanelMouseEnter() {
    if (settings.locked) {
        ipcRenderer.invoke('set-click-through', false);
    }
}

function handleSettingsPanelMouseLeave() {
    if (settings.locked) {
        ipcRenderer.invoke('set-click-through', true);
    }
}

// 计时器面板鼠标事件处理
function handleTimerPanelMouseEnter() {
    if (settings.locked) {
        ipcRenderer.invoke('set-click-through', false);
    }
}

function handleTimerPanelMouseLeave() {
    if (settings.locked) {
        ipcRenderer.invoke('set-click-through', true);
    }
}

function updateSettingsUI() {
    document.getElementById('opacitySlider').value = settings.opacity;
    document.getElementById('opacityValue').textContent = Math.round(settings.opacity * 100) + '%';
    document.getElementById('widthInput').value = settings.width;
    document.getElementById('heightInput').value = settings.height;
    document.getElementById('alwaysOnTopCheck').checked = settings.alwaysOnTop;
    document.getElementById('refreshInterval').value = settings.refreshInterval;
    document.getElementById('combatTimeoutEnabled').checked = settings.combatTimeoutEnabled;
    document.getElementById('combatTimeout').value = settings.combatTimeout;

    // 初始化战斗超时设置的显示状态
    const timeoutSettings = document.getElementById('combatTimeoutSettings');
    if (timeoutSettings) {
        timeoutSettings.style.display = settings.combatTimeoutEnabled ? 'flex' : 'none';
    }

    // 个性化设置
    const fontSizeInput = document.getElementById('fontSizeInput');
    const themeColorInput = document.getElementById('themeColorInput');
    if (fontSizeInput) fontSizeInput.value = settings.fontSize;
    if (themeColorInput) themeColorInput.value = settings.themeColor;
    const compactCheck = document.getElementById('compactModeCheck');
    if (compactCheck) compactCheck.checked = settings.compactMode;
    const themeRadios = document.querySelectorAll('input[name="themeMode"]');
    themeRadios.forEach(r => r.checked = (r.value === settings.themeMode));

    // 初始化CSS透明度变量
    document.documentElement.style.setProperty('--bg-opacity', settings.opacity);

    // 初始化时也直接更新元素透明度
    updateElementsOpacity(settings.opacity);

    applyThemeToDocument();

    // 从本地选择恢复条高度
    const savedSize = localStorage.getItem('overlay_damageSize') || 'medium';
    applyDamageSize(savedSize);
    const sizeRadio = document.querySelector(`input[name="damageSize"][value="${savedSize}"]`);
    if (sizeRadio) sizeRadio.checked = true;
}

// 设置更新函数
async function updateOpacity() {
    const opacity = parseFloat(document.getElementById('opacitySlider').value);
    document.getElementById('opacityValue').textContent = Math.round(opacity * 100) + '%';

    // 更新CSS变量，控制框体内部透明度
    document.documentElement.style.setProperty('--bg-opacity', opacity);
    console.log('🎨 透明度已更新:', opacity, '- CSS变量已设置');

    // 直接更新所有关键元素的透明度，确保立即生效
    updateElementsOpacity(opacity);

    settings.opacity = opacity;
    await ipcRenderer.invoke('update-settings', { opacity });
}

// 直接更新所有元素透明度的函数
function updateElementsOpacity(opacity) {
    console.log('🔧 直接更新元素透明度:', opacity);

    // 统计找到的元素数量
    const damageItems = document.querySelectorAll('.damage-item');
    const rankBadges = document.querySelectorAll('.rank-badge');
    const chips = document.querySelectorAll('.chip');
    const skillItems = document.querySelectorAll('.skill-item');

    console.log(' 找到的元素:', {
        damageItems: damageItems.length,
        rankBadges: rankBadges.length,
        chips: chips.length,
        skillItems: skillItems.length
    });

    // 更新玩家条背景
    document.querySelectorAll('.damage-item').forEach(item => {
        if (item.classList.contains('rank-1')) {
            item.style.background = `linear-gradient(135deg, rgba(255, 206, 84, ${opacity * 0.35}) 0%, rgba(255, 255, 255, ${opacity * 0.12}) 100%)`;
        } else if (item.classList.contains('rank-2')) {
            item.style.background = `linear-gradient(135deg, rgba(192, 57, 43, ${opacity * 0.25}) 0%, rgba(255, 255, 255, ${opacity * 0.12}) 100%)`;
        } else if (item.classList.contains('rank-3')) {
            item.style.background = `linear-gradient(135deg, rgba(142, 68, 173, ${opacity * 0.25}) 0%, rgba(255, 255, 255, ${opacity * 0.12}) 100%)`;
        }
    });

    // 更新排行标签
    document.querySelectorAll('.rank-badge').forEach(badge => {
        badge.style.background = `rgba(255, 255, 255, ${opacity * 0.25})`;
    });

    // 更新芯片背景
    document.querySelectorAll('.chip').forEach(chip => {
        chip.style.background = `rgba(255, 255, 255, ${opacity * 0.1})`;
        chip.style.borderColor = `rgba(255, 255, 255, ${opacity * 0.18})`;
    });

    // 更新技能项背景
    document.querySelectorAll('.skill-item').forEach(item => {
        item.style.background = `rgba(255, 255, 255, ${opacity * 0.08})`;
    });

    // 更新技能详情容器
    document.querySelectorAll('.skill-details').forEach(details => {
        details.style.background = `rgba(0, 0, 0, ${opacity * 0.4})`;
        details.style.borderColor = `rgba(255, 206, 84, ${opacity * 0.4})`;
    });

    // 更新技能进度条背景
    document.querySelectorAll('.skill-bar-row').forEach(bar => {
        bar.style.background = `rgba(255, 255, 255, ${opacity * 0.12})`;
    });

    // 更新迷你进度条
    document.querySelectorAll('.mini-bar').forEach(bar => {
        bar.style.background = `rgba(255, 255, 255, ${opacity * 0.25})`;
    });

    console.log('✅ 所有元素透明度已直接更新');
}

async function updateSize() {
    const width = parseInt(document.getElementById('widthInput').value);
    const height = parseInt(document.getElementById('heightInput').value);

    settings.width = width;
    settings.height = height;
    await ipcRenderer.invoke('update-settings', { width, height });
}

async function updateAlwaysOnTop() {
    const alwaysOnTop = document.getElementById('alwaysOnTopCheck').checked;

    settings.alwaysOnTop = alwaysOnTop;
    await ipcRenderer.invoke('update-settings', { alwaysOnTop });
}

function updateRefreshInterval() {
    const interval = parseInt(document.getElementById('refreshInterval').value);
    settings.refreshInterval = interval;

    // 重新启动数据刷新
    startDataRefresh();
}

function updateCombatTimeoutEnabled() {
    const enabled = document.getElementById('combatTimeoutEnabled').checked;
    settings.combatTimeoutEnabled = enabled;

    // 控制下拉框的显示/隐藏
    const timeoutSettings = document.getElementById('combatTimeoutSettings');
    if (timeoutSettings) {
        timeoutSettings.style.display = enabled ? 'flex' : 'none';
    }

    // 同时更新服务器设置
    updateCombatTimeout();
}

async function updateCombatTimeout() {
    const timeout = parseInt(document.getElementById('combatTimeout').value);
    settings.combatTimeout = timeout;

    // 通知服务器更新战斗超时时间，如果禁用则传递-1
    const actualTimeout = settings.combatTimeoutEnabled ? timeout : -1;
    try {
        await fetchData(getApiUrl(`/api/combat-timeout?timeout=${actualTimeout}&enabled=${settings.combatTimeoutEnabled}`));
        console.log(`战斗超时功能已${settings.combatTimeoutEnabled ? '启用' : '禁用'}，超时时间: ${timeout}ms`);
    } catch (error) {
        console.error('更新战斗超时设置失败:', error);
    }
}

// 同步战斗超时状态
async function syncCombatTimeoutStatus() {
    try {
        const response = await fetchData(getApiUrl('/api/combat-timeout-status'));
        if (response.code === 0) {
            // 更新本地设置以匹配服务器状态
            settings.combatTimeoutEnabled = response.enabled;
            if (response.timeout && response.timeout > 0) {
                settings.combatTimeout = response.timeout;
            }

            // 更新UI以反映服务器状态
            const checkbox = document.getElementById('combatTimeoutEnabled');
            const timeoutSelect = document.getElementById('combatTimeout');
            const timeoutSettings = document.getElementById('combatTimeoutSettings');

            if (checkbox) checkbox.checked = settings.combatTimeoutEnabled;
            if (timeoutSelect) timeoutSelect.value = settings.combatTimeout;
            if (timeoutSettings) {
                timeoutSettings.style.display = settings.combatTimeoutEnabled ? 'flex' : 'none';
            }

            console.log('战斗超时状态已同步:', response);
        }
    } catch (error) {
        console.warn('无法同步战斗超时状态，使用本地设置:', error);
    }
}



// 个性化：主题与字体
function applyThemeToDocument() {
    const root = document.documentElement;
    // 主题主色：空值用#000
    root.style.setProperty('--theme-color', settings.themeColor || '#000000');
    root.style.setProperty('--font-size-base', `${settings.fontSize}px`);
    document.body.classList.toggle('compact-mode', settings.compactMode);
    document.body.classList.toggle('theme-light', settings.themeMode === 'light');
}

function updateFontSizeSetting() {
    const value = parseInt(document.getElementById('fontSizeInput').value, 10);
    if (Number.isFinite(value) && value >= 10 && value <= 20) {
        settings.fontSize = value;
        localStorage.setItem('overlay_fontSize', String(value));
        applyThemeToDocument();
    }
}

function updateThemeColorSetting() {
    const value = document.getElementById('themeColorInput').value;
    if (value) {
        settings.themeColor = value;
        localStorage.setItem('overlay_themeColor', value);
        applyThemeToDocument();
    }
}

// 紧凑模式与主题切换
function updateCompactMode() {
    const checked = document.getElementById('compactModeCheck').checked;
    settings.compactMode = checked;
    localStorage.setItem('overlay_compact', checked ? '1' : '0');
    applyThemeToDocument();
}

function updateThemeMode() {
    const checked = document.querySelector('input[name="themeMode"]:checked');
    if (checked) {
        settings.themeMode = checked.value;
        localStorage.setItem('overlay_themeMode', settings.themeMode);
        applyThemeToDocument();
    }
}

async function resetPosition() {
    const newSettings = { x: 100, y: 100 };
    settings = { ...settings, ...newSettings };
    await ipcRenderer.invoke('update-settings', newSettings);
}

// 窗口控制函数
async function minimizeWindow() {
    await ipcRenderer.invoke('minimize-app');
}

async function closeWindow() {
    stopDataRefresh();
    await ipcRenderer.invoke('close-app');
}

// 页面加载完成后初始化
document.addEventListener('DOMContentLoaded', init);

// 页面卸载时清理资源
window.addEventListener('beforeunload', () => {
    stopDataRefresh();
    stopCaptureStatusCheck();
    if (timerState.timerInterval) {
        clearInterval(timerState.timerInterval);
    }
});

// 计时器相关函数
function toggleTimer() {
    const panel = document.getElementById('timerPanel');
    panel.classList.toggle('hidden');

    // 如果处于锁定状态，需要为计时器面板添加鼠标事件
    if (settings.locked) {
        if (!panel.classList.contains('hidden')) {
            // 计时器面板打开时，禁用穿透
            ipcRenderer.invoke('set-click-through', false);
            panel.addEventListener('mouseenter', handleTimerPanelMouseEnter);
            panel.addEventListener('mouseleave', handleTimerPanelMouseLeave);
        } else {
            // 计时器面板关闭时，移除事件监听器并恢复穿透
            panel.removeEventListener('mouseenter', handleTimerPanelMouseEnter);
            panel.removeEventListener('mouseleave', handleTimerPanelMouseLeave);
            ipcRenderer.invoke('set-click-through', true);
        }
    }

    updateTimerDisplay();
}

function hideTimer() {
    const panel = document.getElementById('timerPanel');
    panel.classList.add('hidden');

    // 如果处于锁定状态，需要恢复穿透并移除事件监听器
    if (settings.locked) {
        panel.removeEventListener('mouseenter', handleTimerPanelMouseEnter);
        panel.removeEventListener('mouseleave', handleTimerPanelMouseLeave);
        ipcRenderer.invoke('set-click-through', true);
    }
}

function setTimerDuration(seconds) {
    if (!timerState.isRunning) {
        timerState.duration = seconds;
        timerState.timeLeft = seconds;
        updateTimerDisplay();
        document.getElementById('startTimerBtn').disabled = false;
        document.getElementById('timerMode').textContent = `设置${seconds}秒`;
    }
}

function startTimer() {
    if (timerState.isRunning) return;

    // 检查锁定状态
    if (settings.locked) {
        alert('窗口当前为锁定状态，请先解锁后再使用计时功能');
        return;
    }

    // 保存当前数据作为基准
    fetchDamageData().then(data => {
        timerState.initialData = data;
        console.log('Timer started with initial data:', data);
    }).catch(err => {
        console.log('Warning: Could not fetch initial data:', err);
        timerState.initialData = {};
    });

    timerState.isRunning = true;
    timerState.startTime = Date.now();

    // 进入计时模式时添加交互遮罩，禁止点击
    addInteractionMask();

    // 启动计时器
    timerState.timerInterval = setInterval(() => {
        timerState.timeLeft--;
        updateTimerDisplay();

        if (timerState.timeLeft <= 0) {
            finishTimer();
        }
    }, 1000);

    // 更新UI
    document.getElementById('startTimerBtn').disabled = true;
    document.getElementById('stopTimerBtn').disabled = false;
    document.getElementById('timerStatusText').textContent = '计时中';
    document.getElementById('timerMode').textContent = '计时进行中';

    // 添加计时动画
    document.getElementById('timerText').parentElement.classList.add('counting');

    // 清理数据 - 调用服务器API
    clearServerData();
}

// 二级计时入口：选择预设秒数后，显示 3-2-1 动画后自动开始
function prepareAndStartTimerWithCountdown(seconds) {
    setTimerDuration(seconds);
    showCountdownAndStart();
}

function showCountdownAndStart() {
    const overlay = document.createElement('div');
    overlay.style.cssText = `position: fixed; inset: 0; background: rgba(0,0,0,.6); display: flex; align-items: center; justify-content: center; z-index: 2000;`;
    const box = document.createElement('div');
    box.style.cssText = `color: #fff; font-size: 48px; font-weight: 800; padding: 24px 36px; border: 2px solid rgba(231,174,151,.6); border-radius: 12px; background: rgba(0,0,0,.4);`;
    overlay.appendChild(box);
    // 水印与标题位置
    try {
        const titleBar = document.getElementById('titleBar');
        if (titleBar) {
            overlay.style.alignItems = 'flex-start';
            overlay.style.justifyContent = 'flex-start';
            overlay.style.padding = '12px 16px';
        }
    } catch { }
    document.body.appendChild(overlay);

    const seq = ['3', '2', '1', '计时战斗'];
    let i = 0;
    const tick = () => {
        if (i < seq.length - 1) {
            box.textContent = seq[i++];
            setTimeout(tick, 700);
        } else {
            document.body.removeChild(overlay);
            // 开始计时
            isTimerBattleMode = true;
            startTimer();
            showShortcutFeedback('计时已开始');
        }
    };
    tick();
}

function stopTimer() {
    if (!timerState.isRunning) return;

    timerState.isRunning = false;

    if (timerState.timerInterval) {
        clearInterval(timerState.timerInterval);
        timerState.timerInterval = null;
    }

    // 更新UI
    document.getElementById('startTimerBtn').disabled = false;
    document.getElementById('stopTimerBtn').disabled = true;
    document.getElementById('timerStatusText').textContent = '已停止';
    document.getElementById('timerMode').textContent = '手动停止';

    // 移除动画
    document.getElementById('timerText').parentElement.classList.remove('counting');
}

async function finishTimer() {
    timerState.isRunning = false;

    if (timerState.timerInterval) {
        clearInterval(timerState.timerInterval);
        timerState.timerInterval = null;
    }

    // 自动保存计时桩记录到历史（使用现有的 /api/clear 接口并传入命名）
    try {
        const now = new Date();
        const timestamp = now.getFullYear().toString() +
            (now.getMonth() + 1).toString().padStart(2, '0') +
            now.getDate().toString().padStart(2, '0') +
            now.getHours().toString().padStart(2, '0') +
            now.getMinutes().toString().padStart(2, '0') +
            now.getSeconds().toString().padStart(2, '0');
        const historyName = `计时桩-${timestamp}`;
        console.log('准备保存计时桩历史记录，名称:', historyName);

        const url = getApiUrl(`/api/clear?timerHistory=${encodeURIComponent(historyName)}`);
        const resp = await fetchData(url);
        if (resp && resp.code === 0) {
            console.log('计时桩历史记录已保存:', historyName);
        } else {
            console.error('保存计时桩历史记录失败:', (resp && resp.msg) || '未知错误');
        }
    } catch (error) {
        console.error('保存计时桩历史记录时出错:', error);
    }

    // 更新UI
    document.getElementById('startTimerBtn').disabled = false;
    document.getElementById('stopTimerBtn').disabled = true;
    document.getElementById('timerStatusText').textContent = '计时完成';
    document.getElementById('timerMode').textContent = '时间到！';

    // 添加完成动画
    const timerDisplay = document.getElementById('timerText').parentElement;
    timerDisplay.classList.remove('counting');
    timerDisplay.classList.add('finished');

    // 停止抓包 - 调用服务器API
    stopServerCapture();

    // 显示完成通知
    setTimeout(() => {
        showShortcutFeedback(`计时完成！已保存历史（${timerState.duration}秒）`);
        timerDisplay.classList.remove('finished');
        isTimerBattleMode = false;
        removeInteractionMask();
    }, 1000);
}

function resetTimer() {
    if (timerState.isRunning) {
        stopTimer();
    }

    timerState.timeLeft = timerState.duration;
    timerState.initialData = null;

    updateTimerDisplay();
    document.getElementById('timerStatusText').textContent = '已重置';
    document.getElementById('timerMode').textContent = '就绪';

    // 重置数据 - 调用服务器API
    clearServerData();
}

function exitTimerMode() {
    if (timerState.isRunning) {
        if (confirm('计时器正在运行，确定要退出计时模式吗？')) {
            stopTimer();
        } else {
            return;
        }
    }

    hideTimer();
    document.getElementById('timerStatusText').textContent = '未开始';
    document.getElementById('timerMode').textContent = '就绪';
}

function updateTimerDisplay() {
    const minutes = Math.floor(timerState.timeLeft / 60);
    const seconds = timerState.timeLeft % 60;
    const timeString = `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;

    document.getElementById('timerText').textContent = timeString;
}

// 服务器通信函数
async function clearServerData() {
    try {
        const response = await fetchData(getApiUrl('/api/clear'));
        console.log('Server data cleared:', response);
        document.getElementById('captureStatusText').textContent = '数据已清理';
    } catch (error) {
        console.error('Failed to clear server data:', error);
        document.getElementById('captureStatusText').textContent = '清理失败';
    }
}

// 清空服务端并刷新UI
async function clearServerDataAndUi() {
    try {
        await clearServerData();
        const damageList = document.getElementById('damageList');
        if (damageList) {
            damageList.innerHTML = '<div class="loading"> 已清空数据</div>';
        }
        lastDataHash = '';
        hadDataBefore = false; // 重置标志，避免误判
        // 显示通知提示，强调数据已保存
        showNotification('战斗数据已保存', 'success', 3000);
        // 立即刷新一次显示，同时触发战斗时长轮询下一拍更新
        updateDisplay();
    } catch (e) {
        console.error('清空失败:', e);
    }
}

async function stopServerCapture() {
    try {
        // 这里需要根据实际的服务器API来实现停止抓包功能
        // 目前先模拟停止功能
        console.log('Stop capture request sent');
        document.getElementById('captureStatusText').textContent = '抓包已停止';

        // 实际实现时，可能需要调用类似这样的API：
        // const response = await fetchData('http://localhost:${settings.apiPort}/api/stop-capture');
    } catch (error) {
        console.error('Failed to stop capture:', error);
        document.getElementById('captureStatusText').textContent = '停止失败';
    }
}

// 排序和显示控制函数
function sortPlayers(players) {
    switch (displaySettings.sortBy) {
        case 'damage':
            players.sort((a, b) => b.total_damage.total - a.total_damage.total);
            break;
        case 'healing':
            players.sort((a, b) => {
                const aHealingData = normalizeHealingData(a);
                const bHealingData = normalizeHealingData(b);
                const aHealing = aHealingData ? aHealingData.total : 0;
                const bHealing = bHealingData ? bHealingData.total : 0;
                return bHealing - aHealing;
            });
            break;
        case 'dps':
            players.sort((a, b) => b.total_dps - a.total_dps);
            break;
        case 'instant':
            players.sort((a, b) => (b.realtime_dps || b.realtime_dps_value || 0) - (a.realtime_dps || a.realtime_dps_value || 0));
            break;
        case 'hps':
            players.sort((a, b) => {
                const aHps = a.total_hps || 0;
                const bHps = b.total_hps || 0;
                return bHps - aHps;
            });
            break;
        case 'taken':
            players.sort((a, b) => {
                const aTaken = a.taken_damage || 0;
                const bTaken = b.taken_damage || 0;
                return bTaken - aTaken;
            });
            break;
        case 'profession':
            players.sort((a, b) => {
                const aProfession = a.profession || '未知';
                const bProfession = b.profession || '未知';
                return aProfession.localeCompare(bProfession, 'zh-CN');
            });
            break;
        default:
            players.sort((a, b) => b.total_damage.total - a.total_damage.total);
            break;
    }
}

function setSortMode(sortType) {
    displaySettings.sortBy = sortType;
    // 同步下拉单选框
    const radio = document.querySelector(`input[name="sortBy"][value="${sortType}"]`);
    if (radio) radio.checked = true;
    // 以综合DPS排序时隐藏秒伤chip
    const dpsChipStyleId = 'dps-chip-style';
    let style = document.getElementById(dpsChipStyleId);
    if (!style) { style = document.createElement('style'); style.id = dpsChipStyleId; document.head.appendChild(style); }
    style.textContent = (sortType === 'dps') ? `.dps-chip{display:none!important;}` : '';
    // 重新刷新显示
    updateDisplay();
}

// 初始化时从勾选项恢复排序
function initSortFromMenu() {
    const checked = document.querySelector('input[name="sortBy"]:checked');
    if (checked) {
        displaySettings.sortBy = checked.value;
    }
    // 重新刷新显示
    updateDisplay();
}

function updateDisplaySettings() {
    // 下拉勾选项已迁移至设置面板，这里仅从当前 DOM 获取（若存在）否则使用原值
    const sd = document.getElementById('showDamageDropdown');
    const sh = document.getElementById('showHealingDropdown');
    const st = document.getElementById('showTakenDropdown');
    const sp = document.getElementById('showProfessionDropdown');
    const scr = document.getElementById('showCritRate');
    const sih = document.getElementById('showInstantHeal');
    const sid = document.getElementById('showInstantDps');
    if (sd) displaySettings.showDamage = sd.checked;
    if (sh) displaySettings.showHealing = sh.checked;
    if (st) displaySettings.showTaken = st.checked;
    if (sp) displaySettings.showProfession = sp.checked;
    if (scr) displaySettings.showCritRate = scr.checked;
    if (sih) displaySettings.showInstantHeal = sih.checked;
    if (sid) displaySettings.showInstantDps = sid.checked;
    
    // 立即更新总览柱状图的显示状态
    updateOverviewBars(lastFetchedUserMap || {});
    
    // 以综合DPS排序时隐藏秒伤chip
    const dpsChipStyleId = 'dps-chip-style';
    let style = document.getElementById(dpsChipStyleId);
    if (!style) { style = document.createElement('style'); style.id = dpsChipStyleId; document.head.appendChild(style); }
    style.textContent = (displaySettings.sortBy === 'dps') ? `.dps-chip{display:none!important;}` : '';
    updateDisplay();
}

// 初始化锁定按钮状态
function initLockButtonState() {
    const lockBtn = document.getElementById('lockBtn');
    const iconImg = lockBtn.querySelector('.btn-icon');

    if (settings.locked) {
        // 如果已锁定，显示解锁图标和红色背景
        lockBtn.classList.add('locked');
        iconImg.src = '../public/解锁.png';
        iconImg.alt = '解锁';
        lockBtn.title = '解锁';
    } else {
        // 如果未锁定，显示锁定图标
        lockBtn.classList.remove('locked');
        iconImg.src = '../public/lock.png';
        iconImg.alt = '锁定';
        lockBtn.title = '锁定';
    }
}

// 锁定/解锁功能
function toggleLock() {
    const titleBar = document.getElementById('titleBar');
    const lockBtn = document.getElementById('lockBtn');
    const iconImg = lockBtn.querySelector('.btn-icon');

    if (settings.locked) {
        // 解锁
        settings.locked = false;
        titleBar.style.pointerEvents = 'auto';
        titleBar.style.webkitAppRegion = 'no-drag';
        titleBar.style.cursor = 'move';
        lockBtn.classList.remove('locked');
        iconImg.src = '../public/lock.png';
        iconImg.alt = '锁定';
        lockBtn.title = '锁定';

        // 恢复拖拽功能
        titleBar.style.webkitAppRegion = 'drag';

        // 通知主进程取消点击穿透
        ipcRenderer.invoke('set-click-through', false);
    } else {
        // 锁定
        settings.locked = true;
        titleBar.style.pointerEvents = 'auto';
        titleBar.style.webkitAppRegion = 'no-drag';
        titleBar.style.cursor = 'pointer';
        lockBtn.classList.add('locked');
        iconImg.src = '../public/解锁.png';
        iconImg.alt = '解锁';
        lockBtn.title = '解锁';

        // 通知主进程设置点击穿透
        ipcRenderer.invoke('set-click-through', true);
    }
}

// 锁定时：鼠标在标题栏或设置面板上，暂时关闭窗口穿透；离开时，恢复穿透
function handleTitleBarMouseEnterTempDisable() {
    ipcRenderer.invoke('set-click-through', false);
}
function handleTitleBarMouseLeaveEnable() {
    // 检查鼠标是否移动到设置面板或计时器面板上，如果是，则不恢复穿透
    if (settings.locked) {
        const settingsPanel = document.getElementById('settingsPanel');
        const timerPanel = document.getElementById('timerPanel');
        const isSettingsVisible = settingsPanel && !settingsPanel.classList.contains('hidden');
        const isTimerVisible = timerPanel && !timerPanel.classList.contains('hidden');

        if (!isSettingsVisible && !isTimerVisible) {
            ipcRenderer.invoke('set-click-through', true);
        }
    }
}

// 显示玩家技能详情页面
async function showPlayerSkillDetails(uid) {
    console.log('showPlayerSkillDetails called with uid:', uid);

    // 设置当前编辑的玩家UID
    currentEditingPlayerUid = uid;

    const mainView = document.getElementById('mainView');
    const skillView = document.getElementById('skillView');

    if (!mainView || !skillView) {
        console.error('找不到主视图或技能视图元素');
        return;
    }

    // 隐藏主视图，显示技能详情视图
    mainView.style.display = 'none';
    skillView.classList.remove('hidden');

    // 获取玩家信息
    const currentData = await fetchDamageData();
    const player = currentData.user[uid];

    if (player) {
        // 更新头部信息
        document.getElementById('skillPlayerName').textContent = `玩家_${uid}`;
        document.getElementById('skillPlayerProfession').textContent = player.profession || '未知';

        // 加载技能详细信息
        await loadAndDisplaySkillDetails(uid, player);
    } else {
        console.error('找不到玩家数据:', uid);
        // 显示错误信息
        document.getElementById('skillDetailsList').innerHTML = '<div class="loading">❌ 找不到玩家数据</div>';
    }
}

// 显示主视图
function showMainView() {
    const mainView = document.getElementById('mainView');
    const skillView = document.getElementById('skillView');

    // 显示主视图，隐藏技能详情视图
    mainView.style.display = 'block';
    skillView.classList.add('hidden');
}

// 加载并显示技能详细信息
async function loadAndDisplaySkillDetails(uid, playerData) {
    const skillDetailsList = document.getElementById('skillDetailsList');

    try {
        // 显示加载状态
        skillDetailsList.innerHTML = '<div class="loading">🔄 加载技能信息中...</div>';

        // 尝试获取技能详细统计，根据当前排序类型排序
        let sortParam = '';
        if (displaySettings.sortBy === 'healing') {
            sortParam = '?sort=healing';
        } else if (displaySettings.sortBy === 'taken') {
            sortParam = '?sort=taken';
        } else {
            sortParam = '?sort=damage';
        }
        const response = await fetchData(getApiUrl(`/api/skill-stats/${uid}${sortParam}`));
        let skillsData = {};

        if (response.code === 0 && (response.skills || response.data)) {
            skillsData = response.skills || response.data;
        }

        // 生成技能详情HTML
        const html = generateSkillDetailsHTML(playerData, skillsData);
        skillDetailsList.innerHTML = html;

    } catch (error) {
        console.error('加载技能详细信息失败:', error);
        skillDetailsList.innerHTML = '<div class="loading">❌ 加载失败</div>';
    }
}

// 生成技能详情HTML
function generateSkillDetailsHTML(playerData, skillsData) {
    const totalDamage = playerData.total_damage.total;
    const normalizedPlayerDataHealing = normalizeHealingData(playerData);
    const totalHealing = normalizedPlayerDataHealing ? normalizedPlayerDataHealing.total : 0;
    const critRate = playerData.total_count.total > 0 ?
        ((playerData.total_count.critical / playerData.total_count.total) * 100).toFixed(1) : '0.0';
    const luckyRate = playerData.total_count.total > 0 ?
        ((playerData.total_count.lucky / playerData.total_count.total) * 100).toFixed(1) : '0.0';

    // 构建可过滤的数组（支持 skill_type）
    const listRaw = Array.isArray(skillsData) ? skillsData : Object.entries(skillsData).map(([skillId, s]) => ({
        skill_id: Number(skillId),
        skill_name: s.skill_name || s.name || (s.skillInfo && s.skillInfo.name) || `技能${skillId}`,
        skill_type: s.skill_type || (s.skillInfo && s.skillInfo.type) || 'damage',
        total_damage: s.total_damage || s.total || (s.stats && (s.stats.total || (s.stats.stats && s.stats.stats.total))) || 0,
        count: s.count || (s.stats && (s.stats.count && s.stats.count.total)) || 0
    }));
    // 如果当前不在healing模式，优先展示伤害技能，过滤掉治疗/承伤
    const list = (displaySettings.sortBy === 'healing') ? listRaw : listRaw.filter(s => s.skill_type !== 'healing' && s.skill_type !== 'taken');

    // 迷你切换：仅当排序为healing且玩家有治疗时展示
    const shouldShowMiniToggle = (displaySettings.sortBy === 'healing') && (totalHealing > 0);

    let html = `
        <div class="skill-summary">
            <div class="skill-summary-title">📊 战斗统计概览</div>
            <div class="skill-summary-stats">
                <div class="skill-summary-item"><span class="skill-summary-label">总伤害</span><span class="skill-summary-value">${formatNumber(totalDamage)}</span></div>
                <div class="skill-summary-item"><span class="skill-summary-label">DPS</span><span class="skill-summary-value">${playerData.total_dps.toFixed(0)}</span></div>
                ${totalHealing > 0 ? `<div class="skill-summary-item"><span class="skill-summary-label">总治疗</span><span class="skill-summary-value healing-value">${formatNumber(totalHealing)}</span></div>` : ''}
                ${totalHealing > 0 ? `<div class="skill-summary-item"><span class="skill-summary-label">HPS</span><span class="skill-summary-value healing-value">${(playerData.total_hps || 0).toFixed(0)}</span></div>` : ''}
                <div class="skill-summary-item"><span class="skill-summary-label">暴击率</span><span class="skill-summary-value">${critRate}%</span></div>
                <div class="skill-summary-item"><span class="skill-summary-label">幸运率</span><span class="skill-summary-value">${luckyRate}%</span></div>
            </div>
        </div>
        ${shouldShowMiniToggle ? `<div id="miniHealDamageToggle" style="display:flex;gap:6px;align-items:center;margin:8px 0 4px 0;">
            <span style="font-size:12px;color:#9aa">显示:</span>
            <button data-mode="healing" class="mini-toggle" style="padding:2px 6px;border:1px solid rgba(128,128,128,.4);border-radius:4px;background:rgba(40,70,40,.9);color:#b8f0c8;cursor:pointer;">治疗</button>
            <button data-mode="damage" class="mini-toggle" style="padding:2px 6px;border:1px solid rgba(128,128,128,.4);border-radius:4px;background:rgba(60,60,60,.8);color:#f0f0f0;cursor:pointer;">伤害</button>
        </div>` : ''}
    `;

    // 默认过滤数组：治疗模式默认显示治疗，否则默认显示伤害
    const defaultMode = shouldShowMiniToggle ? 'healing' : 'damage';
    const filtered = list.filter(s => defaultMode === 'healing' ? (s.skill_type === 'healing') : (s.skill_type !== 'healing' && s.skill_type !== 'taken'));

    // 绘制列表（简化：仅显示过滤后的）
    if (filtered.length > 0) {
        html += `<div class="skill-list-title">🗡️ 技能详细分析</div>`;
        html += `<div class="skill-chart-container">`;
        filtered.sort((a,b)=>b.total_damage-a.total_damage).forEach((skill, idx) => {
            const base = (skill.skill_type === 'healing') ? (totalHealing || 1) : (totalDamage || 1);
            const pct = ((skill.total_damage / base) * 100).toFixed(1);
            const bar = (skill.skill_type === 'healing') ? '#2ecc71' : '#c00d07';
            html += `
                <div class="skill-chart-item">
                    <div class="skill-chart-header"><div class="skill-chart-name">${skill.skill_name}</div><div class="skill-chart-percentage">${pct}%</div></div>
                    <div class="skill-chart-bar-container"><div class="skill-chart-bar" style="width:${pct}%; background:${bar}"></div></div>
                    <div class="skill-chart-stats"><span class="skill-chart-damage">${formatNumber(skill.total_damage)}</span><span class="skill-chart-count">${skill.count || 0}次</span></div>
                </div>`;
        });
        html += `</div>`;
    } else {
        html += '<div class="loading">📭 暂无技能数据</div>';
    }

    // 绑定切换（渲染后由外部调用时再绑定）
    setTimeout(()=>{
        const toggle = document.getElementById('miniHealDamageToggle');
        if (!toggle) return;
        toggle.addEventListener('click', (e)=>{
            const btn = e.target.closest('.mini-toggle');
            if (!btn) return;
            const mode = btn.getAttribute('data-mode');
            const filtered2 = list.filter(s => mode === 'healing' ? (s.skill_type === 'healing') : (s.skill_type !== 'healing' && s.skill_type !== 'taken'));
            const container = document.getElementById('skillDetailsList');
            if (!container) return;
            const newHtml = generateSkillDetailsHTML(playerData, filtered2);
            container.innerHTML = newHtml;
        });
        // 首次进入奶妈模式时，若默认显示治疗，且需要可视化提示，可以临时高亮按钮
        try {
            const btnHealing = toggle.querySelector('[data-mode="healing"]');
            if (btnHealing) btnHealing.style.outline = '1px solid #2ecc71';
            setTimeout(()=>{ if (btnHealing) btnHealing.style.outline = ''; }, 1200);
        } catch {}
    },0);

    return html;
}

// 昵称编辑功能
let currentEditingPlayerUid = null;

function showNicknameEditModal() {
    console.log('显示昵称编辑弹窗');
    const modal = document.getElementById('nicknameEditModal');
    const uidElement = document.getElementById('editingPlayerUid');
    const nicknameInput = document.getElementById('nicknameInput');

    // 获取当前正在查看的玩家信息
    if (currentEditingPlayerUid) {
        uidElement.textContent = currentEditingPlayerUid;

        // 获取当前昵称并填入输入框
        let currentNickname = '';
        // 优先使用主列表中该UID的昵称
        const card = document.querySelector(`.damage-item[data-uid="${currentEditingPlayerUid}"] .player-name`);
        if (card && card.textContent) currentNickname = card.textContent.trim();
        // 回退到技能页标题
        if (!currentNickname) {
            const playerNameElement = document.getElementById('skillPlayerName');
            currentNickname = playerNameElement ? playerNameElement.textContent.trim() : '';
        }
        nicknameInput.value = currentNickname;

        modal.classList.remove('hidden');
        nicknameInput.focus();
        nicknameInput.select();
    }
}

function hideNicknameEditModal() {
    console.log('隐藏昵称编辑弹窗');
    const modal = document.getElementById('nicknameEditModal');
    modal.classList.add('hidden');

    // 清空输入框
    document.getElementById('nicknameInput').value = '';
}

async function savePlayerNickname() {
    const nicknameInput = document.getElementById('nicknameInput');
    const newNickname = nicknameInput.value.trim();

    if (!newNickname) {
        alert('请输入昵称');
        nicknameInput.focus();
        return;
    }

    if (!currentEditingPlayerUid) {
        alert('无法获取玩家ID');
        return;
    }

    try {
        console.log('保存昵称:', { uid: currentEditingPlayerUid, nickname: newNickname });

        // 发送昵称更新请求到服务器
        const postData = JSON.stringify({
            uid: currentEditingPlayerUid,
            nickname: newNickname
        });

        const xhr = new XMLHttpRequest();
        xhr.open('POST', getApiUrl('/api/update-nickname'));
        xhr.setRequestHeader('Content-Type', 'application/json');

        xhr.onload = function () {
            if (xhr.status >= 200 && xhr.status < 300) {
                try {
                    const response = JSON.parse(xhr.responseText);
                    if (response.code === 0 || response.success) {
                        // 更新本地昵称缓存
                        allNicknames[currentEditingPlayerUid] = newNickname;

                        // 更新本地显示
                        const skillPlayerName = document.getElementById('skillPlayerName');
                        if (skillPlayerName) {
                            skillPlayerName.textContent = newNickname;
                        }
                        hideNicknameEditModal();

                        // 如果昵称管理窗口是打开的，立即刷新列表
                        const nicknameManager = document.getElementById('nicknameManagerModal');
                        if (nicknameManager && !nicknameManager.classList.contains('hidden')) {
                            filterNicknames();
                        }

                        // 刷新主列表显示
                        updateDisplay();

                        console.log('昵称保存成功');
                    } else {
                        alert('昵称保存失败: ' + (response.message || response.msg || '未知错误'));
                    }
                } catch (e) {
                    console.error('服务器响应解析失败:', e, '原始响应:', xhr.responseText);
                    // 尝试更宽松的解析
                    if (xhr.responseText.includes('成功') || xhr.responseText.includes('success')) {
                        // 如果响应包含成功关键词，认为操作成功
                        allNicknames[currentEditingPlayerUid] = newNickname;
                        const skillPlayerName = document.getElementById('skillPlayerName');
                        if (skillPlayerName) {
                            skillPlayerName.textContent = newNickname;
                        }
                        hideNicknameEditModal();
                        updateDisplay();
                        console.log('昵称保存成功（宽松解析）');
                    } else {
                        alert('服务器响应解析失败，请检查网络连接或联系管理员');
                    }
                }
            } else {
                alert('昵称保存失败: HTTP ' + xhr.status);
            }
        };

        xhr.onerror = function () {
            alert('网络错误，无法保存昵称');
        };

        xhr.send(postData);

    } catch (error) {
        console.error('保存昵称时出错:', error);
        alert('保存昵称时出错: ' + error.message);
    }
}

// 昵称管理功能
let allNicknames = {};
let filteredNicknames = {};

async function showNicknameManager() {
    console.log('显示昵称管理窗口');
    const modal = document.getElementById('nicknameManagerModal');
    modal.classList.remove('hidden');

    // 加载昵称数据
    await loadNicknames();
}

function hideNicknameManager() {
    console.log('隐藏昵称管理窗口');
    const modal = document.getElementById('nicknameManagerModal');
    modal.classList.add('hidden');

    // 清空搜索框
    document.getElementById('nicknameSearch').value = '';
}

async function loadNicknames() {
    try {
        const xhr = new XMLHttpRequest();
        xhr.open('GET', getApiUrl('/api/nicknames'));

        xhr.onload = function () {
            if (xhr.status >= 200 && xhr.status < 300) {
                try {
                    const response = JSON.parse(xhr.responseText);
                    if (response.code === 0) {
                        allNicknames = response.data || {};
                        filteredNicknames = { ...allNicknames };
                        renderNicknamesList();
                    } else {
                        console.error('获取昵称数据失败:', response.msg);
                        showNicknamesError('获取昵称数据失败');
                    }
                } catch (e) {
                    console.error('解析昵称数据失败:', e);
                    showNicknamesError('解析数据失败');
                }
            } else {
                console.error('获取昵称数据失败: HTTP', xhr.status);
                showNicknamesError('网络请求失败');
            }
        };

        xhr.onerror = function () {
            console.error('获取昵称数据失败: 网络错误');
            showNicknamesError('网络连接失败');
        };

        xhr.send();
    } catch (error) {
        console.error('加载昵称数据时出错:', error);
        showNicknamesError('加载失败: ' + error.message);
    }
}

function renderNicknamesList() {
    const nicknamesList = document.getElementById('nicknamesList');

    if (Object.keys(filteredNicknames).length === 0) {
        nicknamesList.innerHTML = '<div class="loading"> 暂无昵称数据</div>';
        return;
    }

    let html = '';
    Object.entries(filteredNicknames).forEach(([uid, nickname]) => {
        html += `
            <div class="nickname-item" data-uid="${uid}">
                <div class="nickname-info">
                    <div class="nickname-uid">玩家ID: ${uid}</div>
                    <div class="nickname-name">${nickname}</div>
                </div>
                <div class="nickname-actions-item">
                    <button class="edit-nickname-item" data-uid="${uid}" data-nickname="${nickname.replace(/'/g, "\\'")}">编辑</button>
                    <button class="delete-nickname-item" data-uid="${uid}">删除</button>
                </div>
            </div>
        `;
    });

    nicknamesList.innerHTML = html;

    // 为动态生成的按钮添加事件监听器
    document.querySelectorAll('.edit-nickname-item').forEach(btn => {
        btn.addEventListener('click', function (e) {
            e.preventDefault();
            e.stopPropagation();
            const uid = this.dataset.uid;
            const nickname = this.dataset.nickname;

            handleEditNickname(uid, nickname);
        });
    });

    document.querySelectorAll('.delete-nickname-item').forEach(btn => {
        btn.addEventListener('click', function (e) {
            e.preventDefault();
            e.stopPropagation();
            const uid = this.dataset.uid;

            handleDeleteNickname(uid);
        });
    });
}

// 昵称管理事件处理函数已改为onclick直接绑定，不再需要事件委托

function showNicknamesError(message) {
    const nicknamesList = document.getElementById('nicknamesList');
    nicknamesList.innerHTML = `<div class="loading">❌ ${message}</div>`;
}

function filterNicknames() {
    const searchTerm = document.getElementById('nicknameSearch').value.toLowerCase();

    if (!searchTerm) {
        filteredNicknames = { ...allNicknames };
    } else {
        filteredNicknames = {};
        Object.entries(allNicknames).forEach(([uid, nickname]) => {
            if (uid.toLowerCase().includes(searchTerm) ||
                nickname.toLowerCase().includes(searchTerm)) {
                filteredNicknames[uid] = nickname;
            }
        });
    }

    renderNicknamesList();
}

// 删除刷新函数，改为在操作后自动刷新

function showAddNicknameDialog() {
    // 使用自定义对话框而不是prompt
    const modal = document.createElement('div');
    modal.style.cssText = `
        position: fixed; top: 0; left: 0; width: 100%; height: 100%;
        background: rgba(0,0,0,0.8); display: flex; justify-content: center;
        align-items: center; z-index: 10000;
    `;

    const dialog = document.createElement('div');
    dialog.style.cssText = `
        background: #2c3e50; padding: 20px; border-radius: 8px; border: 2px solid #ffce54;
        max-width: 300px; width: 90%;
    `;

    dialog.innerHTML = `
        <h3 style="color: #ffce54; margin: 0 0 15px 0;">添加新昵称</h3>
        <input type="text" id="uidInput" placeholder="请输入玩家ID" 
               style="width: 100%; padding: 8px; margin-bottom: 10px; border: 1px solid #ccc; border-radius: 4px;">
        <input type="text" id="nicknameInput" placeholder="请输入昵称" 
               style="width: 100%; padding: 8px; margin-bottom: 15px; border: 1px solid #ccc; border-radius: 4px;">
        <div style="text-align: right;">
            <button id="cancelAdd" style="margin-right: 10px; padding: 6px 12px; background: #95a5a6; color: white; border: none; border-radius: 4px; cursor: pointer;">取消</button>
            <button id="saveAdd" style="padding: 6px 12px; background: #e74c3c; color: white; border: none; border-radius: 4px; cursor: pointer;">添加</button>
        </div>
    `;

    modal.appendChild(dialog);
    document.body.appendChild(modal);

    // 焦点到输入框
    const uidInput = dialog.querySelector('#uidInput');
    const nicknameInput = dialog.querySelector('#nicknameInput');
    uidInput.focus();

    // 事件处理
    dialog.querySelector('#saveAdd').onclick = async () => {
        const uid = uidInput.value.trim();
        const nickname = nicknameInput.value.trim();
        if (!uid) {
            alert('请输入玩家ID');
            uidInput.focus();
            return;
        }
        if (!nickname) {
            alert('请输入昵称');
            nicknameInput.focus();
            return;
        }

        try {
            await saveNicknameInManager(uid, nickname);
            // 添加成功后立即刷新昵称列表和主界面
            filterNicknames();
            updateDisplay();
            document.body.removeChild(modal);
        } catch (error) {
            console.error('添加昵称失败:', error);
            alert('添加昵称失败: ' + error.message);
            // 不关闭弹窗，让用户重试
        }
    };

    dialog.querySelector('#cancelAdd').onclick = () => {
        document.body.removeChild(modal);
    };

    // 键盘处理
    [uidInput, nicknameInput].forEach(input => {
        input.onkeydown = (e) => {
            if (e.key === 'Enter') {
                dialog.querySelector('#saveAdd').click();
            } else if (e.key === 'Escape') {
                dialog.querySelector('#cancelAdd').click();
            }
        };
    });
}

function saveNicknameInManager(uid, nickname) {
    return new Promise((resolve, reject) => {
        try {
            const xhr = new XMLHttpRequest();
            xhr.open('POST', getApiUrl('/api/update-nickname'));
            xhr.setRequestHeader('Content-Type', 'application/json');

            xhr.onload = function () {
                if (xhr.status >= 200 && xhr.status < 300) {
                    try {
                        const response = JSON.parse(xhr.responseText);
                        if (response.code === 0 || response.success) {
                            console.log('昵称保存成功');
                            if (nickname) {
                                allNicknames[uid] = nickname;
                            } else {
                                delete allNicknames[uid]; // 删除空昵称
                            }
                            resolve(response);
                        } else {
                            const errorMsg = response.message || response.msg || '未知错误';
                            reject(new Error('保存失败: ' + errorMsg));
                        }
                    } catch (e) {
                        console.error('服务器响应解析失败:', e, '原始响应:', xhr.responseText);
                        // 尝试更宽松的解析
                        if (xhr.responseText.includes('成功') || xhr.responseText.includes('success')) {
                            // 如果响应包含成功关键词，认为操作成功
                            if (nickname) {
                                allNicknames[uid] = nickname;
                            } else {
                                delete allNicknames[uid];
                            }
                            console.log('昵称保存成功（宽松解析）');
                            resolve({ code: 0, msg: '昵称更新成功' });
                        } else {
                            reject(new Error('服务器响应解析失败，请检查网络连接或联系管理员'));
                        }
                    }
                } else {
                    reject(new Error('保存失败: HTTP ' + xhr.status));
                }
            };

            xhr.onerror = function () {
                reject(new Error('网络错误，无法保存昵称'));
            };

            const postData = JSON.stringify({ uid, nickname });
            xhr.send(postData);
        } catch (error) {
            console.error('保存昵称时出错:', error);
            reject(new Error('保存昵称时出错: ' + error.message));
        }
    });
}

// 这些函数已被全局onclick函数替代

// 昵称管理的全局点击处理函数
window.handleEditNickname = function (uid, currentNickname) {
    console.log('编辑昵称被点击，UID:', uid, '当前昵称:', currentNickname);
    // 设置当前编辑的玩家UID和昵称
    currentEditingPlayerUid = uid;

    // 直接显示昵称编辑弹窗并预填充当前昵称
    const modal = document.getElementById('nicknameEditModal');
    const uidElement = document.getElementById('editingPlayerUid');
    const nicknameInput = document.getElementById('nicknameInput');
    if (!modal || !uidElement || !nicknameInput) return;

    uidElement.textContent = uid;
    nicknameInput.value = currentNickname || '';
    modal.classList.remove('hidden');
    nicknameInput.focus();
    nicknameInput.select();
};

window.handleDeleteNickname = function (uid) {
    console.log('删除昵称被点击，UID:', uid);
    if (!confirm(`确定要删除玩家ID ${uid} 的昵称吗？`)) return;

    // 删除昵称就是设置为空字符串
    saveNicknameInManager(uid, '').then(() => {
        delete allNicknames[uid];
        filterNicknames();
        updateDisplay();
    });
};

// 修复其他按钮的点击问题
window.handleManageNicknames = function () {
    console.log('管理昵称按钮被点击');
    showNicknameManager();
};

// 刷新昵称功能已移除，改为自动刷新

window.handleAddNickname = function () {
    console.log('添加昵称按钮被点击');
    showAddNicknameDialog();
};

window.handleCloseNicknameManager = function () {
    console.log('关闭昵称管理被点击');
    hideNicknameManager();
};

// 历史记录功能
async function showHistoryModal() {
    console.log('显示历史记录窗口');
    const modal = document.getElementById('historyModal');
    modal.classList.remove('hidden');
    await loadHistoryList();
}

function hideHistoryModal() {
    console.log('隐藏历史记录窗口');
    const modal = document.getElementById('historyModal');
    modal.classList.add('hidden');
}

async function loadHistoryList() {
    console.log('加载历史记录列表');
    const historyList = document.getElementById('historyList');

    try {
        historyList.innerHTML = '<div class="loading"> 加载中...</div>';

        const response = await fetchData(getApiUrl('/api/history'));

        if (response.code === 0) {
            const histories = response.data || [];
            renderHistoryList(histories);
        } else {
            historyList.innerHTML = `<div class="loading">❌ 加载失败: ${response.msg || '未知错误'}</div>`;
        }
    } catch (error) {
        console.error('加载历史记录失败:', error);
        historyList.innerHTML = `<div class="loading">❌ 网络错误: ${error.message}</div>`;
    }
}

function renderHistoryList(histories) {
    const historyList = document.getElementById('historyList');

    if (histories.length === 0) {
        historyList.innerHTML = '<div class="loading">暂无历史记录</div>';
        return;
    }

    let html = '';
    histories.forEach(history => {
        html += `
            <div class="history-item" onclick="showHistoryDetail('${history.id}')">
                <div class="history-info">
                    <div class="history-time">${history.displayTime}</div>
                    <div class="history-summary">
                        <span>${history.totalPlayers}名玩家</span>
                        <span>战斗${history.totalTime}秒</span>
                    </div>
                </div>
                <div class="history-stats">
                    <div class="history-stat">
                        <div class="history-stat-value">${formatNumber(history.totalDamage)}</div>
                        <div class="history-stat-label">总伤害</div>
                    </div>
                    <div class="history-stat">
                        <div class="history-stat-value">${formatNumber(history.totalHealing)}</div>
                        <div class="history-stat-label">总治疗</div>
                    </div>
                </div>
            </div>
        `;
    });

    historyList.innerHTML = html;
}

// 全局函数以支持onclick调用
window.showHistoryDetail = async function (historyId) {
    console.log('显示历史记录详情:', historyId);

    try {
        // 使用新窗口显示历史详情
        await ipcRenderer.invoke('open-history-detail', historyId);
    } catch (error) {
        console.error('打开历史详情窗口失败:', error);
        alert('无法打开历史详情窗口: ' + error.message);
    }
};

function renderHistoryDetail(historyData) {
    const content = document.getElementById('historyDetailContent');
    const title = document.getElementById('historyDetailTitle');

    title.textContent = ` ${historyData.displayTime}`;

    // 渲染总览信息
    let html = `
        <div class="history-detail-header">
            <div class="history-detail-title">
                <span>战斗总览</span>
                <span style="font-size: 12px; color: rgba(255,255,255,0.7);">ID: ${historyData.id}</span>
            </div>
            <div class="history-detail-meta">
                <div class="history-detail-stat">
                    <div class="history-detail-stat-value">${historyData.summary.totalPlayers}</div>
                    <div class="history-detail-stat-label">参战玩家</div>
                </div>
                <div class="history-detail-stat">
                    <div class="history-detail-stat-value">${formatNumber(historyData.summary.totalDamage)}</div>
                    <div class="history-detail-stat-label">总伤害</div>
                </div>
                <div class="history-detail-stat">
                    <div class="history-detail-stat-value">${formatNumber(historyData.summary.totalHealing)}</div>
                    <div class="history-detail-stat-label">总治疗</div>
                </div>
                <div class="history-detail-stat">
                    <div class="history-detail-stat-value">${formatNumber(historyData.summary.totalTaken)}</div>
                    <div class="history-detail-stat-label">总承伤</div>
                </div>
                <div class="history-detail-stat">
                    <div class="history-detail-stat-value">${historyData.summary.totalTime}秒</div>
                    <div class="history-detail-stat-label">战斗时长</div>
                </div>
            </div>
        </div>
    `;

    // 渲染玩家详情
    const players = Object.values(historyData.players).sort((a, b) =>
        (b.total_damage?.total || 0) - (a.total_damage?.total || 0)
    );

    html += `
        <div class="history-players">
            <div class="history-players-title">玩家详情 (${players.length}人)</div>
    `;

    players.forEach((player, index) => {
        const rank = index + 1;
        html += `
            <div class="history-player">
                <div class="history-player-header">
                    <div class="history-player-name">#${rank} ${player.name}</div>
                    <div class="history-player-profession">${player.profession}</div>
                </div>
                <div class="history-player-stats">
                    <div class="history-player-stat">
                        <div class="history-player-stat-value">${formatNumber(player.total_damage?.total || 0)}</div>
                        <div class="history-player-stat-label">总伤害</div>
                    </div>
                    <div class="history-player-stat">
                        <div class="history-player-stat-value">${(player.total_dps || 0).toFixed(0)}</div>
                        <div class="history-player-stat-label">瞬时伤害</div>
                    </div>
                    <div class="history-player-stat">
                        <div class="history-player-stat-value">${formatNumber(normalizeHealingData(player)?.total || 0)}</div>
                        <div class="history-player-stat-label">总治疗</div>
                    </div>
                    <div class="history-player-stat">
                        <div class="history-player-stat-value">${(player.total_hps || 0).toFixed(0)}</div>
                        <div class="history-player-stat-label">瞬时治疗</div>
                    </div>
                    <div class="history-player-stat">
                        <div class="history-player-stat-value">${formatNumber(player.taken_damage || 0)}</div>
                        <div class="history-player-stat-label">承受伤害</div>
                    </div>
                    <div class="history-player-stat">
                        <div class="history-player-stat-value">${player.critRate || '0.0'}%</div>
                        <div class="history-player-stat-label">暴击率</div>
                    </div>
                    <div class="history-player-stat">
                        <div class="history-player-stat-value">${player.luckyRate || '0.0'}%</div>
                        <div class="history-player-stat-label">幸运率</div>
                    </div>
                    <div class="history-player-stat">
                        <div class="history-player-stat-value">${(player.realtime_dps_max || 0).toFixed(0)}</div>
                        <div class="history-player-stat-label">最大瞬时</div>
                    </div>
                </div>
            </div>
        `;
    });

    html += `
            </div>
        </div>
    `;

    content.innerHTML = html;
}

function hideHistoryDetail() {
    console.log('隐藏历史详情窗口');
    const modal = document.getElementById('historyDetailModal');
    modal.classList.add('hidden');
}

async function clearAllHistory() {
    if (!confirm('确定要清空所有历史记录吗？此操作不可恢复！')) {
        return;
    }

    try {
        const xhr = new XMLHttpRequest();
        xhr.open('DELETE', getApiUrl('/api/history'));

        xhr.onload = function () {
            if (xhr.status >= 200 && xhr.status < 300) {
                try {
                    const response = JSON.parse(xhr.responseText);
                    if (response.code === 0) {
                        console.log('历史记录已清空');
                        loadHistoryList(); // 重新加载列表
                    } else {
                        alert('清空失败: ' + (response.msg || '未知错误'));
                    }
                } catch (e) {
                    alert('响应解析失败');
                }
            } else {
                alert('清空失败: HTTP ' + xhr.status);
            }
        };

        xhr.onerror = function () {
            alert('网络错误，无法清空历史记录');
        };

        xhr.send();
    } catch (error) {
        console.error('清空历史记录时出错:', error);
        alert('清空历史记录时出错: ' + error.message);
    }
}

// 键盘快捷键处理
function handleKeyboardShortcuts(event) {
    // 如果焦点在输入框中，不处理快捷键
    if (event.target.tagName === 'INPUT' || event.target.tagName === 'TEXTAREA' || event.target.tagName === 'SELECT') {
        return;
    }

    // 检查自定义锁定快捷键
    if (checkCustomShortcut(event)) {
        event.preventDefault();
        toggleLock();
        showShortcutFeedback(settings.locked ? '窗口已锁定' : '窗口已解锁');
        return;
    }

    // 仅保留F9清空快捷键
    if (event.key === 'F9') {
        event.preventDefault();
        clearServerDataAndUi();
        // 注释掉重复的通知，clearServerDataAndUi()内部已有通知
        // showShortcutFeedback('战斗数据已清空');
        return;
    }

    // 保留F8作为备用快捷键
    if (event.key === 'F8') {
        event.preventDefault();
        toggleLock();
        showShortcutFeedback(settings.locked ? '窗口已锁定' : '窗口已解锁');
        return;
    }
}

let pendingAltA = false;
let isTimerBattleMode = false;

function addInteractionMask() {
    let mask = document.getElementById('interactionMask');
    if (mask) return;
    mask = document.createElement('div');
    mask.id = 'interactionMask';
    mask.style.cssText = 'position:fixed;inset:0;z-index:1500;background:rgba(0,0,0,0.25);cursor:not-allowed;';
    mask.addEventListener('click', (e) => e.stopPropagation(), true);
    document.body.appendChild(mask);
}

function removeInteractionMask() {
    const mask = document.getElementById('interactionMask');
    if (mask && mask.parentNode) mask.parentNode.removeChild(mask);
}

// 显示快捷键反馈
function showShortcutFeedback(message) {
    // 创建反馈提示
    const feedback = document.createElement('div');
    feedback.className = 'shortcut-feedback';
    feedback.innerHTML = `
        <div class="shortcut-feedback-content">
          
            <span class="shortcut-feedback-message">${message}</span>
        </div>
    `;

    // 添加样式
    feedback.style.cssText = `
        position: fixed;
        top: 20px;
        right: 20px;
        background: rgba(0, 0, 0, 0.9);
        color: white;
        padding: 12px 16px;
        border-radius: 6px;
        border-left: 4px solid var(--theme-color, #e7ae97);
        font-size: 14px;
        z-index: 10000;
        animation: shortcutFadeInOut 2s ease-in-out;
        pointer-events: none;
    `;

    // 添加动画样式
    if (!document.querySelector('#shortcut-feedback-style')) {
        const style = document.createElement('style');
        style.id = 'shortcut-feedback-style';
        style.textContent = `
            @keyframes shortcutFadeInOut {
                0% { opacity: 0; transform: translateX(100%); }
                15% { opacity: 1; transform: translateX(0); }
                85% { opacity: 1; transform: translateX(0); }
                100% { opacity: 0; transform: translateX(100%); }
            }
            .shortcut-feedback-content {
                display: flex;
                align-items: center;
                gap: 8px;
            }
            .shortcut-feedback-key {
                font-family: 'Courier New', monospace;
                font-weight: bold;
                background: rgba(255, 255, 255, 0.2);
                padding: 2px 6px;
                border-radius: 3px;
                font-size: 12px;
            }
            .shortcut-feedback-message {
                font-size: 13px;
            }
        `;
        document.head.appendChild(style);
    }

    document.body.appendChild(feedback);

    // 2秒后移除
    setTimeout(() => {
        if (feedback.parentNode) {
            feedback.parentNode.removeChild(feedback);
        }
    }, 2000);
}

// 应用启动时初始化
document.addEventListener('DOMContentLoaded', init);

// 自定义快捷键相关变量
let customLockShortcut = 'F8';
let isRecordingShortcut = false;

// 初始化自定义快捷键
function initCustomShortcuts() {
    // 从localStorage加载保存的快捷键
    const savedShortcut = localStorage.getItem('customLockShortcut');
    if (savedShortcut) {
        customLockShortcut = savedShortcut;
        updateShortcutDisplay();
    }

    // 通知主进程当前的快捷键设置
    ipcRenderer.invoke('update-lock-shortcut', customLockShortcut).catch(error => {
        console.error('初始化快捷键失败:', error);
    });

    // 绑定快捷键修改按钮事件
    const changeShortcutBtn = document.getElementById('changeLockShortcut');
    if (changeShortcutBtn) {
        changeShortcutBtn.addEventListener('click', showCustomShortcutPanel);
    }

    // 绑定关闭快捷键面板事件
    const closeShortcutPanel = document.getElementById('closeShortcutPanel');
    if (closeShortcutPanel) {
        closeShortcutPanel.addEventListener('click', hideCustomShortcutPanel);
    }

    // 绑定重置快捷键事件
    const resetShortcutBtn = document.getElementById('resetLockShortcut');
    if (resetShortcutBtn) {
        resetShortcutBtn.addEventListener('click', resetLockShortcut);
    }

    // 绑定快捷键输入框事件
    const shortcutInput = document.getElementById('lockShortcutInput');
    if (shortcutInput) {
        shortcutInput.addEventListener('click', startRecordingShortcut);
        shortcutInput.addEventListener('keydown', handleShortcutKeydown);
        shortcutInput.addEventListener('blur', stopRecordingShortcut);
    }
}

// 显示自定义快捷键面板
function showCustomShortcutPanel() {
    const panel = document.getElementById('customShortcutPanel');
    if (panel) {
        panel.classList.remove('hidden');
        // 设置当前快捷键到输入框
        const shortcutInput = document.getElementById('lockShortcutInput');
        if (shortcutInput) {
            shortcutInput.value = customLockShortcut;
        }
    }
}

// 隐藏自定义快捷键面板
function hideCustomShortcutPanel() {
    const panel = document.getElementById('customShortcutPanel');
    if (panel) {
        panel.classList.add('hidden');
        stopRecordingShortcut();
    }
}

// 开始录制快捷键
function startRecordingShortcut() {
    isRecordingShortcut = true;
    const shortcutInput = document.getElementById('lockShortcutInput');
    if (shortcutInput) {
        shortcutInput.classList.add('recording');
        shortcutInput.value = '请按下快捷键...';
        shortcutInput.focus();
    }
}

// 停止录制快捷键
function stopRecordingShortcut() {
    isRecordingShortcut = false;
    const shortcutInput = document.getElementById('lockShortcutInput');
    if (shortcutInput) {
        shortcutInput.classList.remove('recording');
        shortcutInput.value = customLockShortcut;
    }
}

// 处理快捷键按键
function handleShortcutKeydown(event) {
    if (!isRecordingShortcut) return;

    event.preventDefault();

    const keys = [];
    if (event.ctrlKey) keys.push('Ctrl');
    if (event.shiftKey) keys.push('Shift');
    if (event.altKey) keys.push('Alt');
    if (event.metaKey) keys.push('Meta');

    // 添加主键
    if (event.key !== 'Control' && event.key !== 'Shift' && event.key !== 'Alt' && event.key !== 'Meta') {
        keys.push(event.key.toUpperCase());
    }

    if (keys.length > 0) {
        const newShortcut = keys.join('+');
        customLockShortcut = newShortcut;

        // 保存到localStorage
        localStorage.setItem('customLockShortcut', newShortcut);

        // 通知主进程更新全局快捷键
        ipcRenderer.invoke('update-lock-shortcut', newShortcut).catch(error => {
            console.error('更新快捷键失败:', error);
        });

        // 更新显示
        updateShortcutDisplay();

        // 停止录制
        stopRecordingShortcut();

        // 显示成功提示
        showNotification(`快捷键已更改为: ${newShortcut}`, 'success', 2000);

        // 隐藏面板
        hideCustomShortcutPanel();
    }
}

// 重置锁定快捷键
function resetLockShortcut() {
    customLockShortcut = 'F8';
    localStorage.setItem('customLockShortcut', 'F8');

    // 通知主进程更新全局快捷键
    ipcRenderer.invoke('update-lock-shortcut', 'F8').catch(error => {
        console.error('重置快捷键失败:', error);
    });

    updateShortcutDisplay();

    const shortcutInput = document.getElementById('lockShortcutInput');
    if (shortcutInput) {
        shortcutInput.value = 'F8';
    }

    showNotification('快捷键已重置为: F8', 'success', 2000);
}

// 更新快捷键显示
function updateShortcutDisplay() {
    const displayElement = document.getElementById('lockShortcutDisplay');
    if (displayElement) {
        displayElement.textContent = customLockShortcut;
    }
}

// 检查快捷键是否匹配
function checkCustomShortcut(event) {
    const keys = [];
    if (event.ctrlKey) keys.push('Ctrl');
    if (event.shiftKey) keys.push('Shift');
    if (event.altKey) keys.push('Alt');
    if (event.metaKey) keys.push('Meta');

    // 添加主键
    if (event.key !== 'Control' && event.key !== 'Shift' && event.key !== 'Alt' && event.key !== 'Meta') {
        keys.push(event.key.toUpperCase());
    }

    const pressedShortcut = keys.join('+');
    return pressedShortcut === customLockShortcut;
}

// ========== 网卡配置功能 ==========

// 网卡操作状态管理（防重复操作）
let isLoadingNetworkDevices = false;
let isSwitchingNetworkDevice = false;

// 简化的网卡列表加载（防重复加载，参照源码简洁架构）
// 网卡加载重试计数和冷却时间
let networkLoadRetryCount = 0;
let lastNetworkLoadAttempt = 0;
const MAX_NETWORK_RETRY = 3;
const RETRY_COOLDOWN = 5000; // 5秒冷却

async function loadNetworkDevices(forceRetry = false) {
    // 防止重复加载
    if (isLoadingNetworkDevices) {
        console.log('网卡加载中，跳过重复请求');
        return false;
    }

    // 重试冷却检查（除非强制重试）
    const now = Date.now();
    if (!forceRetry && (now - lastNetworkLoadAttempt) < RETRY_COOLDOWN) {
        console.log(`网卡加载冷却中，剩余${Math.ceil((RETRY_COOLDOWN - (now - lastNetworkLoadAttempt)) / 1000)}秒`);
        return false;
    }

    // 重试次数检查
    if (!forceRetry && networkLoadRetryCount >= MAX_NETWORK_RETRY) {
        console.log('网卡加载重试次数已达上限，需要手动重试');
        showPersistentNetworkError();
        return false;
    }

    isLoadingNetworkDevices = true;
    lastNetworkLoadAttempt = now;
    if (!forceRetry) networkLoadRetryCount++;

    const currentDeviceInfo = document.getElementById('currentDeviceInfo');
    const networkDeviceSelect = document.getElementById('networkDeviceSelect');
    const confirmDeviceBtn = document.getElementById('confirmDeviceBtn');
    const deviceStatus = document.getElementById('deviceStatus');

    try {
        // 显示加载状态
        if (currentDeviceInfo) currentDeviceInfo.textContent = '加载中...';
        if (networkDeviceSelect) networkDeviceSelect.disabled = true;
        if (confirmDeviceBtn) confirmDeviceBtn.disabled = true;
        if (deviceStatus) {
            deviceStatus.textContent = '状态: 加载中...';
            deviceStatus.className = 'status-text warning';
        }

        // 网卡加载使用IPv4地址，避免IPv6解析问题
        const response = await fetchData(getApiUrl('/api/network-devices'), 1, 6000);

        if (response.code === 0 && response.data && response.data.length > 0) {
            // 更新当前网卡信息
            if (currentDeviceInfo) {
                const currentDevice = response.data.find(device => device.isCurrent);
                if (currentDevice) {
                    const star = currentDevice.recommended ? '★ ' : '';
                    currentDeviceInfo.textContent = `${star}${currentDevice.index}. ${currentDevice.description} — ${currentDevice.name}`;
                } else {
                    currentDeviceInfo.textContent = '未知';
                }
            }

            // 更新网卡选择下拉框
            if (networkDeviceSelect) {
                networkDeviceSelect.innerHTML = '';
                const currentIndex = response.currentDevice;

                response.data.forEach(device => {
                    const option = document.createElement('option');
                    option.value = device.index;
                    const star = device.recommended ? '★ ' : '';
                    option.textContent = `${star}${device.index}. ${device.description} — ${device.name}`;
                    if (device.recommended) option.style.fontWeight = '700';
                    if (device.index === currentIndex || device.isCurrent) {
                        option.selected = true;
                    }
                    networkDeviceSelect.appendChild(option);
                });
                networkDeviceSelect.disabled = false;
            }

            // 启用确认按钮
            if (confirmDeviceBtn) confirmDeviceBtn.disabled = false;

            // 更新状态
            if (deviceStatus) {
                deviceStatus.textContent = '状态: 已加载';
                deviceStatus.className = 'status-text success';
            }

            // 成功加载时重置重试计数器
            networkLoadRetryCount = 0;
            console.log('网卡列表加载成功，重试计数器已重置');
            return true;
        } else {
            throw new Error(response.msg || '网卡列表为空');
        }

    } catch (error) {
        console.error('网卡加载失败:', error);
        
        // 智能错误诊断和fallback机制
        console.log('🔍 正在诊断网络连接问题...');
        const isHealthy = await checkNetworkHealth();
        
        let diagnosticMessage = error.message;
        if (!isHealthy) {
            diagnosticMessage = '本地API服务连接失败，请检查服务器是否正常运行';
        } else if (error.message.includes('Request timeout')) {
            diagnosticMessage = '网卡服务响应超时，可能是场景切换导致';
        }

        // 显示错误状态
        if (currentDeviceInfo) currentDeviceInfo.textContent = '加载失败 - ' + diagnosticMessage;
        
        // 智能重试按钮：显示剩余重试次数和冷却时间
        const remainingRetries = MAX_NETWORK_RETRY - networkLoadRetryCount;
        const retryButtonText = remainingRetries > 0 ? `重试 (${remainingRetries}次)` : '强制重试';
        const retryButtonAction = remainingRetries > 0 ? 'loadNetworkDevices()' : 'loadNetworkDevices(true)';
        
        if (deviceStatus) {
            deviceStatus.innerHTML = `
                <span class="status-text error">状态: ${diagnosticMessage}</span>
                <button onclick="${retryButtonAction}" style="margin-left: 10px; padding: 4px 8px; background: #4a90e2; color: white; border: none; border-radius: 4px; cursor: pointer;">${retryButtonText}</button>
            `;
        }

        showNotification(`网卡加载失败 (${networkLoadRetryCount}/${MAX_NETWORK_RETRY}): ${diagnosticMessage}`, 'error', 5000);
        return false;
    } finally {
        // 重置加载状态
        isLoadingNetworkDevices = false;
    }
}

// 显示持续的网络错误状态（达到重试上限时）
function showPersistentNetworkError() {
    const currentDeviceInfo = document.getElementById('currentDeviceInfo');
    const deviceStatus = document.getElementById('deviceStatus');
    
    if (currentDeviceInfo) {
        currentDeviceInfo.textContent = '网卡服务连接失败 - 请检查后端服务状态';
    }
    
    if (deviceStatus) {
        deviceStatus.innerHTML = `
            <span class="status-text error">状态: 连接失败，重试次数已达上限</span>
            <button onclick="resetNetworkRetry()" style="margin-left: 10px; padding: 4px 8px; background: #f39c12; color: white; border: none; border-radius: 4px; cursor: pointer;">重置重试</button>
            <button onclick="loadNetworkDevices(true)" style="margin-left: 5px; padding: 4px 8px; background: #e74c3c; color: white; border: none; border-radius: 4px; cursor: pointer;">强制重试</button>
        `;
    }
    
    showNotification('网卡加载重试次数已达上限，请检查后端服务或手动重试', 'error', 10000);
}

// 重置网络重试计数器
function resetNetworkRetry() {
    networkLoadRetryCount = 0;
    lastNetworkLoadAttempt = 0;
    console.log('网络重试计数器已重置');
    showNotification('重试计数器已重置，可以重新尝试加载网卡', 'success', 3000);
    
    // 立即尝试重新加载
    setTimeout(() => {
        loadNetworkDevices();
    }, 500);
}

// 确认切换网卡（防重复切换）
async function confirmSwitchNetworkDevice() {
    // 防止重复切换
    if (isSwitchingNetworkDevice) {
        console.log('网卡切换中，跳过重复请求');
        return;
    }

    const networkDeviceSelect = document.getElementById('networkDeviceSelect');
    const deviceIndex = networkDeviceSelect ? networkDeviceSelect.value : '';
    if (!deviceIndex) return;

    isSwitchingNetworkDevice = true;

    const deviceStatus = document.getElementById('deviceStatus');
    const currentDeviceInfo = document.getElementById('currentDeviceInfo');

    try {
        // 暂停窗口置顶，给足15秒交互时间
        try { await ipcRenderer.invoke('pause-always-on-top', { pause: true, timeoutMs: 15000 }); } catch { }

        if (deviceStatus) {
            deviceStatus.textContent = '状态: 切换中...';
            deviceStatus.className = 'status-text warning';
        }
        if (networkDeviceSelect) networkDeviceSelect.disabled = true;

        // 显示切换提示
        showNotification('正在切换网卡，请稍候...', 'info', 3000);

        // 网卡切换请求（使用IPv4地址，避免回环地址解析问题）
        const result = await fetchDataPost(getApiUrl('/api/network-device'),
            { deviceIndex: parseInt(deviceIndex, 10) },
            1, // 1次重试，处理场景切换波动
            10000 // 10秒超时，减少等待时间
        );
        if (result.code === 0) {
            // 更新UI显示
            if (currentDeviceInfo) {
                currentDeviceInfo.textContent = `${result.data.deviceIndex}. ${result.data.deviceDescription} — ${result.data.deviceName}`;
            }
            if (deviceStatus) {
                deviceStatus.textContent = '状态: 网卡切换成功';
                deviceStatus.className = 'status-text success';
            }

            showNotification(`网卡已切换: ${result.data.deviceDescription}`, 'success', 3000);

            // 立即更新主界面数据
            updateDisplay();
            startDataRefresh();

            // 网卡切换成功后自动关闭设置面板，并恢复置顶
            setTimeout(() => {
                const settingsPanel = document.getElementById('settingsPanel');
                if (settingsPanel) {
                    settingsPanel.classList.add('hidden');
                }
                
                // 确保恢复置顶状态
                if (settings.alwaysOnTop) {
                    try { 
                        ipcRenderer.invoke('pause-always-on-top', { pause: false }); 
                        console.log('🔺 网卡切换完成，自动恢复窗口置顶');
                    } catch (e) {
                        console.warn('恢复置顶失败:', e.message);
                    }
                }
            }, 1500);

            // 提示用户按P切线（如果需要）
            setTimeout(() => {
                showNotification('没数据显示要按P切线', 'info', 5000);
            }, 2000);
        } else {
            throw new Error(result.msg || '网卡切换失败');
        }

    } catch (error) {
        console.error('网卡切换最终失败:', error);

        if (deviceStatus) {
            deviceStatus.innerHTML = `
                <span class="status-text error">状态: 切换失败 - ${error.message}</span>
                <button onclick="confirmSwitchNetworkDevice()" style="margin-left: 10px; padding: 4px 8px; background: #4a90e2; color: white; border: none; border-radius: 4px; cursor: pointer;">重试</button>
            `;
        }

        showNotification(`网卡切换失败: ${error.message}`, 'error', 5000);
    } finally {
        if (networkDeviceSelect) networkDeviceSelect.disabled = false;
        // 恢复窗口置顶
        try { await ipcRenderer.invoke('pause-always-on-top', { pause: false }); } catch { }
        // 重置切换状态
        isSwitchingNetworkDevice = false;
    }
}

// 初始化网卡配置
function initNetworkDeviceConfig() {
    // 在设置面板显示时加载网卡列表
    const settingsBtn = document.getElementById('settingsBtn');
    if (settingsBtn) {
        settingsBtn.addEventListener('click', () => {
            // 延迟加载，确保设置面板已显示
            setTimeout(() => {
                loadNetworkDevices();
            }, 100);
        });
    }

    // 移除定期健康检查机制（参照源码简洁架构）
    // 源码中没有复杂的健康检查，只在用户主动操作时加载网卡信息
}

// 移除复杂的抓包状态监控（参照源码简洁架构）

// 生成当前可见玩家的伤害占比文案
function buildDamageShareText(userMap) {
    const players = Object.values(userMap || {});
    if (!players.length) return '（无数据）';
    // 以总伤害排序
    players.sort((a,b)=> (b.total_damage?.total||0) - (a.total_damage?.total||0));
    const totalDamage = players.reduce((s,p)=> s + (p.total_damage?.total||0), 0) || 1;
    const lines = players.slice(0,5).map((p,idx)=>{
        const rank = idx+1;
        const job = p.profession || '未知';
        const name = p.nickname || p.name || `玩家_${p.uid}`;
        const pct = ((p.total_damage?.total||0) / totalDamage * 100).toFixed(1);
        return `${rank}# ${job} ${name} ${pct}%`;
    });
    return lines.join('\n') + '\nby_小红猫ACT';
}

// 复制到剪贴板并提示
async function copyDamageShareToClipboard() {
    try {
        const text = buildDamageShareText(lastFetchedUserMap || {});
        await navigator.clipboard.writeText(text);
        showToast(`已复制：${text}`);
        // 尝试自动在游戏内发送（需游戏处于前台）
        try { await ipcRenderer.invoke('simulate-chat-send'); } catch {}
    } catch (e) {
        try {
            const ta = document.createElement('textarea');
            ta.value = buildDamageShareText(lastFetchedUserMap || {});
            document.body.appendChild(ta); ta.select(); document.execCommand('copy'); ta.remove();
            showToast('已复制到剪贴板');
            try { await ipcRenderer.invoke('simulate-chat-send'); } catch {}
        } catch (err) {
            console.error('复制失败', err);
            showToast('复制失败');
        }
    }
}

// 在战斗下拉菜单里注入一个按钮
function injectCopyShareMenu() {
    const menu = document.getElementById('combatMenu');
    if (!menu || menu.__shareInjected) return;
    const btn = document.createElement('div');
    btn.className = 'dropdown-header dropdown-option';
    btn.textContent = '一键复制伤害占比';
    btn.title = '复制TOP占比，进入游戏聊天后手动按Enter粘贴再回车发送';
    btn.addEventListener('click', copyDamageShareToClipboard);
    // 插到"查看历史战斗记录"之后
    const anchors = menu.querySelectorAll('.dropdown-header.dropdown-option');
    if (anchors.length >= 2) {
        anchors[1].after(btn);
    } else {
        menu.appendChild(btn);
    }
    menu.__shareInjected = true;
}

// 简易toast
function showToast(msg) {
    const el = document.createElement('div');
    el.style.cssText = 'position:fixed;bottom:20px;left:50%;transform:translateX(-50%);background:rgba(0,0,0,.7);color:#fff;padding:6px 10px;border-radius:4px;z-index:99999;font-size:12px;';
    el.textContent = msg;
    document.body.appendChild(el);
    setTimeout(()=>{ el.remove(); }, 2000);
}

// 初始化时注入
window.addEventListener('DOMContentLoaded', ()=>{
    try { injectCopyShareMenu(); } catch {}
});
